diff -urN systemd-216/docs/gudev/html/index.html systemd-217/docs/gudev/html/index.html
--- systemd-216/docs/gudev/html/index.html	2014-08-19 15:58:25.807937264 -0700
+++ systemd-217/docs/gudev/html/index.html	2014-10-28 11:06:01.727590557 -0700
@@ -15,7 +15,7 @@
 <div>
 <div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">GUdev Reference Manual</p></th></tr></table></div>
 <div><p class="releaseinfo">
-       For version 216
+       For version 217
  — the latest version of this
        documentation can be found at
        <a class="ulink" href="http://www.freedesktop.org/software/systemd/gudev/" target="_top">
diff -urN systemd-216/docs/gudev/Makefile.in systemd-217/docs/gudev/Makefile.in
--- systemd-216/docs/gudev/Makefile.in	2014-08-19 14:25:16.913861095 -0700
+++ systemd-217/docs/gudev/Makefile.in	2014-10-28 09:32:21.224295784 -0700
@@ -160,7 +160,6 @@
 ELFUTILS_LIBS = @ELFUTILS_LIBS@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
-FIRMWARE_PATH = @FIRMWARE_PATH@
 GCRYPT_CFLAGS = @GCRYPT_CFLAGS@
 GCRYPT_LIBS = @GCRYPT_LIBS@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -286,6 +285,8 @@
 SYSTEM_SYSVRCND_PATH = @SYSTEM_SYSVRCND_PATH@
 SYSTEM_UID_MAX = @SYSTEM_UID_MAX@
 TELINIT = @TELINIT@
+TERMINAL_CFLAGS = @TERMINAL_CFLAGS@
+TERMINAL_LIBS = @TERMINAL_LIBS@
 TTY_GID = @TTY_GID@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
diff -urN systemd-216/docs/gudev/version.xml systemd-217/docs/gudev/version.xml
--- systemd-216/docs/gudev/version.xml	2014-08-19 14:25:23.416864271 -0700
+++ systemd-217/docs/gudev/version.xml	2014-10-28 09:32:30.553455712 -0700
@@ -1 +1 @@
-216
+217
diff -urN systemd-216/docs/libudev/html/index.html systemd-217/docs/libudev/html/index.html
--- systemd-216/docs/libudev/html/index.html	2014-08-19 15:58:25.658946175 -0700
+++ systemd-217/docs/libudev/html/index.html	2014-10-28 11:06:01.647590645 -0700
@@ -15,7 +15,7 @@
 <div>
 <div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">libudev Reference Manual</p></th></tr></table></div>
 <div><p class="releaseinfo">
-       For version 216
+       For version 217
  — the latest version of this
        documentation can be found at
        <a class="ulink" href="http://www.freedesktop.org/software/systemd/libudev/" target="_top">
diff -urN systemd-216/docs/libudev/Makefile.in systemd-217/docs/libudev/Makefile.in
--- systemd-216/docs/libudev/Makefile.in	2014-08-19 14:25:16.968861122 -0700
+++ systemd-217/docs/libudev/Makefile.in	2014-10-28 09:32:21.334297694 -0700
@@ -160,7 +160,6 @@
 ELFUTILS_LIBS = @ELFUTILS_LIBS@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
-FIRMWARE_PATH = @FIRMWARE_PATH@
 GCRYPT_CFLAGS = @GCRYPT_CFLAGS@
 GCRYPT_LIBS = @GCRYPT_LIBS@
 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
@@ -286,6 +285,8 @@
 SYSTEM_SYSVRCND_PATH = @SYSTEM_SYSVRCND_PATH@
 SYSTEM_UID_MAX = @SYSTEM_UID_MAX@
 TELINIT = @TELINIT@
+TERMINAL_CFLAGS = @TERMINAL_CFLAGS@
+TERMINAL_LIBS = @TERMINAL_LIBS@
 TTY_GID = @TTY_GID@
 USE_NLS = @USE_NLS@
 VERSION = @VERSION@
diff -urN systemd-216/docs/libudev/version.xml systemd-217/docs/libudev/version.xml
--- systemd-216/docs/libudev/version.xml	2014-08-19 14:25:23.391864259 -0700
+++ systemd-217/docs/libudev/version.xml	2014-10-28 09:32:30.529455306 -0700
@@ -1 +1 @@
-216
+217
diff -urN systemd-216/hwdb/20-bluetooth-vendor-product.hwdb systemd-217/hwdb/20-bluetooth-vendor-product.hwdb
--- systemd-216/hwdb/20-bluetooth-vendor-product.hwdb	2014-11-03 09:35:33.177229426 -0800
+++ systemd-217/hwdb/20-bluetooth-vendor-product.hwdb	2014-11-03 09:33:49.000179009 -0800
@@ -1166,3 +1166,60 @@
 
 bluetooth:v0182*
  ID_VENDOR_FROM_DATABASE=HOP Ubiquitous
+
+bluetooth:v0183*
+ ID_VENDOR_FROM_DATABASE=To Be Assigned
+
+bluetooth:v0184*
+ ID_VENDOR_FROM_DATABASE=Nectar
+
+bluetooth:v0185*
+ ID_VENDOR_FROM_DATABASE=bel'apps LLC
+
+bluetooth:v0186*
+ ID_VENDOR_FROM_DATABASE=CORE Lighting Ltd
+
+bluetooth:v0187*
+ ID_VENDOR_FROM_DATABASE=Seraphim Sense Ltd
+
+bluetooth:v0188*
+ ID_VENDOR_FROM_DATABASE=Unico RBC
+
+bluetooth:v0189*
+ ID_VENDOR_FROM_DATABASE=Physical Enterprises Inc.
+
+bluetooth:v018A*
+ ID_VENDOR_FROM_DATABASE=Able Trend Technology Limited
+
+bluetooth:v018B*
+ ID_VENDOR_FROM_DATABASE=Konica Minolta, Inc.
+
+bluetooth:v018C*
+ ID_VENDOR_FROM_DATABASE=Wilo SE
+
+bluetooth:v018D*
+ ID_VENDOR_FROM_DATABASE=Extron Design Services
+
+bluetooth:v018E*
+ ID_VENDOR_FROM_DATABASE=Fitbit, Inc.
+
+bluetooth:v018F*
+ ID_VENDOR_FROM_DATABASE=Fireflies Systems
+
+bluetooth:v0190*
+ ID_VENDOR_FROM_DATABASE=Intelletto Technologies Inc.
+
+bluetooth:v0191*
+ ID_VENDOR_FROM_DATABASE=FDK CORPORATION
+
+bluetooth:v0192*
+ ID_VENDOR_FROM_DATABASE=Cloudleaf, Inc
+
+bluetooth:v0193*
+ ID_VENDOR_FROM_DATABASE=Maveric Automation LLC
+
+bluetooth:v0194*
+ ID_VENDOR_FROM_DATABASE=Acoustic Stream Corporation
+
+bluetooth:v0195*
+ ID_VENDOR_FROM_DATABASE=Zuli
diff -urN systemd-216/hwdb/60-keyboard.hwdb systemd-217/hwdb/60-keyboard.hwdb
--- systemd-216/hwdb/60-keyboard.hwdb	2014-11-03 09:35:35.582253676 -0800
+++ systemd-217/hwdb/60-keyboard.hwdb	2014-11-03 09:33:48.794176932 -0800
@@ -181,6 +181,13 @@
  KEYBOARD_KEY_9e=email
  KEYBOARD_KEY_9f=homepage
 
+keyboard:usb:v049Fp0051d*dc*dsc*dp*ic*isc*ip*in01*
+ KEYBOARD_KEY_0c0011=presentation
+ KEYBOARD_KEY_0c0012=addressbook
+ KEYBOARD_KEY_0c0013=info
+ KEYBOARD_KEY_0c0014=prog1
+ KEYBOARD_KEY_0c0015=messenger
+
 ###########################################################
 # Dell
 ###########################################################
@@ -223,6 +230,11 @@
 keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*1210:pvr*
  KEYBOARD_KEY_84=wlan
 
+# Dell Inspiron 1520
+keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*1520:pvr*
+ KEYBOARD_KEY_85=unknown  # Brightness Down, also emitted by acpi-video, ignore
+ KEYBOARD_KEY_86=unknown  # Brightness Up, also emitted by acpi-video, ignore
+
 # Latitude XT2
 keyboard:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*XT2:pvr*
  KEYBOARD_KEY_9b=up                                     # tablet rocker up
diff -urN systemd-216/NEWS systemd-217/NEWS
--- systemd-216/NEWS	2014-11-03 09:35:35.958257467 -0800
+++ systemd-217/NEWS	2014-11-03 09:33:49.129180310 -0800
@@ -2,32 +2,31 @@
 
 CHANGES WITH 217:
 
-        * journalctl gained option -t/--identifier to match on the
-          syslog identifier and --utc option to show timestamps in UTC
-          timezone. journalctl now also accepts -n/--lines=all to
-          disable line cap under a pager.
+        * journalctl gained the new options -t/--identifier= to match
+          on the syslog identifier (aka "tag"), as well as --utc to
+          show log timestamps in the UTC timezone. journalctl now also
+          accepts -n/--lines=all to disable line capping in a pager.
+
+        * journalctl gained a new switch, --flush, that synchronously
+          flushes logs from /run/log/journal to /var/log/journal if
+          persistent storage is enabled. systemd-journal-flush.service
+          now waits until the operation is complete.
 
         * Services can notify the manager before they start a reload
           (by sending RELOADING=1) or shutdown (by sending
-          STOPPING=1). This allows the manager to show the
-          internal state of daemons and closes a race condition
-          when the process is still running but has closed its
-          d-bus connection.
+          STOPPING=1). This allows the manager to track and show the
+          internal state of daemons and closes a race condition when
+          the process is still running but has closed its D-Bus
+          connection.
 
-        * Services with Type=oneshot do not have to have any
-          ExecStart commands.
+        * Services with Type=oneshot do not have to have any ExecStart
+          commands anymore.
 
         * User units are now loaded also from
           $XDG_RUNTIME_DIR/systemd/user/. This is similar to the
           /run/systemd/user directory that was already previously
           supported, but is under the control of the user.
 
-        * A timeout for the start of the system can be configured. The
-          system can be configured to reboot or poweroff if the basic
-          system default target is not reached before the timeout (new
-          StartTimeoutSec=, StartTimeoutAction=,
-          StartTimeoutRebootArgument= options).
-
         * systemd-logind can be configured to also handle lid switch
           events even when the machine is docked or multiple displays
           are attached (HandleLidSwitchDocked= option).
@@ -37,22 +36,16 @@
           generator will parse the resume= option on the kernel
           command-line to trigger resume.
 
-        * systemd-evcat input debugging tool has been added. It will
-          print keys read for the input system and show modifier
-          status.
-
-        * systemd-modeset graphics debugging tool will show undulating
-          rainbows on all connected displays.
-
-        * A user console daemon systemd-consoled has been added. It is
-          a preview, and will so far open a single terminal on each
-          session of the user marked as Desktop=SYSTEMD-CONSOLE.
+        * A user console daemon systemd-consoled has been
+          added. Currently, it is a preview, and will so far open a
+          single terminal on each session of the user marked as
+          Desktop=systemd-console.
 
         * Route metrics can be specified for DHCP routes added by
           systemd-networkd.
 
-        * SELinux context of socket-actived services can be set from
-          the information provided by the remote peer
+        * The SELinux context of socket-activated services can be set
+          from the information provided by the networking stack
           (SELinuxContextFromNet= option).
 
         * Userspace firmware loading support has been removed and
@@ -62,14 +55,16 @@
           minutes, but a warning will be printed after 1 minute to
           help diagnose kernel modules that take a long time to load.
 
-        * Udev rules can now remove tags with TAG-="foobar".
+        * Udev rules can now remove tags on devices with TAG-="foobar".
 
-        * Readhead implementation has been removed. In many
-          circumstatances it didn't give expected benefits even for
+        * systemd's readahead implementation has been removed. In many
+          circumstances it didn't give expected benefits even for
           rotational disk drives and was becoming less relevant in the
-          age of SSDs.
+          age of SSDs. As none of the developers has been using
+          rotating media anymore, and nobody stepped up to actively
+          maintain this component of systemd it has now been removed.
 
-        * Swap units can use Discard= to specify discard options.
+        * Swap units can use Options= to specify discard options.
           Discard options specified for swaps in /etc/fstab are now
           respected.
 
@@ -77,9 +72,124 @@
           virtualization.
 
         * The Password Agent protocol gained support for queries where
-          the user input is shown, useful e.g. for usernames.
-          systemd-ask-password gained a new --echo option to turn
-          that on.
+          the user input is shown, useful e.g. for user names.
+          systemd-ask-password gained a new --echo option to turn that
+          on.
+
+        * The default sysctl.d/ snippets will now set:
+
+                net.core.default_qdisc = fq_codel
+
+          This selects Fair Queuing Controlled Delay as the default
+          queuing discipline for network interfaces. fq_codel helps
+          fight the network bufferbloat problem. It is believed to be
+          a good default with no tuning required for most workloads.
+          Downstream distributions may override this choice. On 10Gbit
+          servers that do not do forwarding, "fq" may perform better.
+          Systems without a good clocksource should use "pfifo_fast".
+
+          [ reverted in this branch ]
+
+        * If kdbus is enabled during build a new option BusPolicy= is
+          available for service units, that allows locking all service
+          processes into a stricter bus policy, in order to limit
+          access to various bus services, or even hide most of them
+          from the service's view entirely.
+
+        * networkctl will now show the .network and .link file
+          networkd has applied to a specific interface.
+
+        * sd-login gained a new API call sd_session_get_desktop() to
+          query which desktop environment has been selected for a
+          session.
+
+        * UNIX utmp support is now compile-time optional to support
+          legacy-free systems.
+
+        * systemctl gained two new commands "add-wants" and
+          "add-requires" for pulling in units from specific targets
+          easily.
+
+        * If the word "rescue" is specified on the kernel command line
+          the system will now boot into rescue mode (aka
+          rescue.target), which was previously available only by
+          specifying "1" or "systemd.unit=rescue.target" on the kernel
+          command line. This new kernel command line option nicely
+          mirrors the already existing "emergency" kernel command line
+          option.
+
+        * New kernel command line options mount.usr=, mount.usrflags=,
+          mount.usrfstype= have been added that match root=, rootflags=,
+          rootfstype= but allow mounting a specific file system to
+          /usr.
+
+        * The $NOTIFY_SOCKET is now also passed to control processes of
+          services, not only the main process.
+
+        * This version reenables support for fsck's -l switch. This
+          means at least version v2.25 of util-linux is required for
+          operation, otherwise dead-locks on device nodes may
+          occur. Again: you need to update util-linux to at least
+          v2.25 when updating systemd to v217.
+
+        * Support for the new ALLOW_INTERACTIVE_AUTHORIZATION D-Bus
+          message flag has been added for all of systemd's PolicyKit
+          authenticated method calls has been added. In particular
+          this now allows optional interactive authorization via
+          PolicyKit for many of PID1's privileged operations such as
+          unit file enabling and disabling.
+
+        * "udevadm hwdb --update" learnt a new switch "--usr" for
+          placing the rebuilt hardware database in /usr instead of
+          /etc. When used only hardware database entries stored in
+          /usr will be used, and any user database entries in /etc are
+          ignored. This functionality is useful for vendors to ship a
+          pre-built database on systems where local configuration is
+          unnecessary or unlikely.
+
+        * Calendar time specifications in .timer units now also
+          understand the strings "semi-annually", "quarterly" and
+          "minutely" as shortcuts (in addition to the preexisting
+          "anually", "hourly", ...).
+
+        * systemd-tmpfiles will now correctly create files in /dev
+          at boot which are marked for creation only at boot. It is
+          recommended to always create static device nodes with 'c!'
+          and 'b!', so that they are created only at boot and not
+          overwritten at runtime.
+
+        * When the watchdog logic is used for a service (WatchdogSec=)
+          and the watchdog timeout is hit the service will now be
+          terminated with SIGABRT (instead of just SIGTERM), in order
+          to make sure a proper coredump and backtrace is
+          generated. This ensures that hanging services will result in
+          similar coredump/backtrace behaviour as services that hit a
+          segmentation fault.
+
+        Contributions from: Andreas Henriksson, Andrei Borzenkov,
+        Angus Gibson, Ansgar Burchardt, Ben Wolsieffer, Brandon L.
+        Black, Christian Hesse, Cristian Rodríguez, Daniel Buch,
+        Daniele Medri, Daniel Mack, Dan Williams, Dave Reisner, David
+        Herrmann, David Sommerseth, David Strauss, Emil Renner
+        Berthing, Eric Cook, Evangelos Foutras, Filipe Brandenburger,
+        Gustavo Sverzut Barbieri, Hans de Goede, Harald Hoyer, Hristo
+        Venev, Hugo Grostabussiat, Ivan Shapovalov, Jan Janssen, Jan
+        Synacek, Jonathan Liu, Juho Son, Karel Zak, Kay Sievers, Klaus
+        Purer, Koen Kooi, Lennart Poettering, Lukas Nykryn, Lukasz
+        Skalski, Łukasz Stelmach, Mantas Mikulėnas, Marcel Holtmann,
+        Marius Tessmann, Marko Myllynen, Martin Pitt, Michael Biebl,
+        Michael Marineau, Michael Olbrich, Michael Scherer, Michal
+        Schmidt, Michal Sekletar, Miroslav Lichvar, Patrik Flykt,
+        Philippe De Swert, Piotr Drąg, Rahul Sundaram, Richard
+        Weinberger, Robert Milasan, Ronny Chevalier, Ruben Kerkhof,
+        Santiago Vila, Sergey Ptashnick, Simon McVittie, Sjoerd
+        Simons, Stefan Brüns, Steven Allen, Steven Noonan, Susant
+        Sahani, Sylvain Plantefève, Thomas Hindoe Paaboel Andersen,
+        Timofey Titovets, Tobias Hunger, Tom Gundersen, Torstein
+        Husebø, Umut Tezduyar Lindskog, WaLyong Cho, Zbigniew
+        Jędrzejewski-Szmek.
+
+        -- Berlin, 2014-10-28
 
 CHANGES WITH 216:
 
@@ -92,6 +202,8 @@
           to their unit files to take over and replace systemd's NTP
           default functionality.
 
+          [ reverted in this branch ]
+
         * systemd-sysusers gained a new line type "r" for configuring
           which UID/GID ranges to allocate system users/groups
           from. Lines of type "u" may now add an additional column
diff -urN systemd-216/README systemd-217/README
--- systemd-216/README	2014-11-03 09:35:24.200138910 -0800
+++ systemd-217/README	2014-10-22 11:23:09.845687439 -0700
@@ -129,11 +129,8 @@
         During runtime, you need the following additional
         dependencies:
 
-        util-linux >= v2.19 (requires fsck -l, agetty -s),
-                      v2.21 required for tests in test/
+        util-linux >= v2.25 required
         dbus >= 1.4.0 (strictly speaking optional, but recommended)
-        sulogin (from util-linux >= 2.22 or sysvinit-tools, optional but recommended,
-                 required for tests in test/)
         dracut (optional)
         PolicyKit (optional)
 
diff -urN systemd-216/shell-completion/bash/systemctl.in systemd-217/shell-completion/bash/systemctl.in
--- systemd-216/shell-completion/bash/systemctl.in	2014-11-03 09:35:24.176138668 -0800
+++ systemd-217/shell-completion/bash/systemctl.in	2014-11-03 09:33:48.737176357 -0800
@@ -52,13 +52,29 @@
 }
 
 __get_all_units      () { { __systemctl $1 list-unit-files; __systemctl $1 list-units --all; } \
-        | { while read -r a b; do echo " $a"; done; }; }
+        | { while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }; }
+__get_template_names () { __systemctl $1 list-unit-files \
+        | { while read -r a b; do [[ $a =~ @\. ]] && echo " ${a%%@.*}@"; done; }; }
+
 __get_active_units   () { __systemctl $1 list-units       \
         | { while read -r a b; do echo " $a"; done; }; }
-__get_startable_units () { {
-        __systemctl $1 list-units --all -t service,timer,socket,mount,automount,path,snapshot,swap
-        __systemctl $1 list-unit-files -t service,timer,socket,mount,automount,path,snapshot,swap; } \
-        | { while read -r a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo " $a"; done; }; }
+__get_startable_units () {
+        # find startable inactive units
+        __filter_units_by_property $mode ActiveState inactive $(
+            __filter_units_by_property $mode CanStart yes $(
+                __systemctl $mode list-unit-files --state enabled,disabled,static | \
+                    { while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }
+                __systemctl $mode list-units --state inactive,failed | \
+                    { while read -r a b; do echo " $a"; done; } ))
+}
+__get_restartable_units () {
+        # filter out masked and not-found
+        __filter_units_by_property $mode CanStart yes $(
+            __systemctl $mode list-unit-files --state enabled,disabled,static | \
+                    { while read -r a b; do [[ $a =~ @\. ]] || echo " $a"; done; }
+            __systemctl $mode list-units | \
+                    { while read -r a b; do echo " $a"; done; } )
+}
 __get_failed_units   () { __systemctl $1 list-units       \
         | { while read -r a b c d; do [[ $c == "failed"   ]] && echo " $a"; done; }; }
 __get_enabled_units  () { __systemctl $1 list-unit-files  \
@@ -67,6 +83,7 @@
         | { while read -r a b c  ; do [[ $b == "disabled" ]] && echo " $a"; done; }; }
 __get_masked_units   () { __systemctl $1 list-unit-files  \
         | { while read -r a b c  ; do [[ $b == "masked"   ]] && echo " $a"; done; }; }
+__get_all_unit_files () { { __systemctl $1 list-unit-files; } | { while read -r a b; do echo " $a"; done; }; }
 
 _systemctl () {
         local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
@@ -132,6 +149,7 @@
          [ISOLATABLE_UNITS]='isolate'
          [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload'
         [RESTARTABLE_UNITS]='restart reload-or-restart'
+         [TARGET_AND_UNITS]='add-wants add-requires'
              [MASKED_UNITS]='unmask'
                      [JOBS]='cancel'
                 [SNAPSHOTS]='delete'
@@ -139,7 +157,8 @@
                [STANDALONE]='daemon-reexec daemon-reload default
                              emergency exit halt hibernate hybrid-sleep kexec list-jobs
                              list-sockets list-timers list-units list-unit-files poweroff
-                             reboot rescue show-environment suspend get-default'
+                             reboot rescue show-environment suspend get-default
+                             is-system-running'
                      [NAME]='snapshot'
                      [FILE]='link'
                   [TARGETS]='set-default'
@@ -165,25 +184,24 @@
                 compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then
-                comps=$( __get_disabled_units $mode )
+                comps=$( __get_disabled_units $mode;
+                        __get_template_names $mode)
                 compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[REENABLABLE_UNITS]}; then
                 comps=$( __get_disabled_units $mode;
-                         __get_enabled_units $mode )
+                         __get_enabled_units $mode;
+                         __get_template_names $mode)
                 compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
-                comps=$( __filter_units_by_property $mode CanStart yes \
-                      $( __get_startable_units $mode))
+                comps=$( __get_startable_units $mode;
+                         __get_template_names $mode)
                 compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
-                comps=$( __filter_units_by_property $mode CanStart yes \
-                      $( __get_all_units $mode \
-                        | while read -r line; do \
-                                [[ "$line" =~ @\.|\.(device|snapshot|socket|timer)$ ]] || echo " $line"; \
-                        done ))
+                comps=$( __get_restartable_units $mode;
+                         __get_template_names $mode)
                 compopt -o filenames
 
         elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then
@@ -209,6 +227,16 @@
                 comps=$( __get_masked_units $mode )
                 compopt -o filenames
 
+        elif __contains_word "$verb" ${VERBS[TARGET_AND_UNITS]}; then
+                if __contains_word "$prev" ${VERBS[TARGET_AND_UNITS]} \
+                || __contains_word "$prev" ${OPTS[STANDALONE]}; then
+                        comps=$( __systemctl $mode list-unit-files --type target --all \
+                        | { while read -r a b; do echo " $a"; done; } )
+                else
+                        comps=$( __get_all_unit_files $mode )
+                fi
+                compopt -o filenames
+
         elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then
                 comps=''
 
diff -urN systemd-216/shell-completion/zsh/_systemctl.in systemd-217/shell-completion/zsh/_systemctl.in
--- systemd-216/shell-completion/zsh/_systemctl.in	2014-07-29 10:51:00.714285638 -0700
+++ systemd-217/shell-completion/zsh/_systemctl.in	2014-11-03 09:33:48.765176640 -0800
@@ -31,6 +31,9 @@
     "disable:Disable one or more unit files"
     "reenable:Reenable one or more unit files"
     "preset:Enable/disable one or more unit files based on preset configuration"
+    "set-default:Set the default target"
+    "get-default:Query the default target"
+    "is-system-running:Query overall status of the system"
     "help:Show documentation for specified units"
     "list-dependencies:Show unit dependency tree"
     "mask:Mask one or more units"
@@ -138,8 +141,29 @@
   done
 }
 
+_systemctl_all_units() { { __systemctl list-unit-files; __systemctl list-units --all; } | { while read -r a b; do [[ $a =~ @\. ]] || echo -E - " $a"; done; } }
+_systemctl_get_template_names() { __systemctl list-unit-files | { while read -r a b; do  [[ $a =~ @\. ]] && echo -E - " ${a%%@.*}@"; done; } }
+
+
 _systemctl_active_units()  {_sys_active_units=(  $(__systemctl list-units          | { while read -r a b; do echo -E - " $a"; done; }) )}
-_systemctl_inactive_units(){_sys_inactive_units=($(__systemctl list-units --all    | { while read -r a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo -E - " $a"; done; }) )}
+
+_systemctl_startable_units(){
+    _sys_startable_units=(_filter_units_by_property ActiveState inactive $(
+                          _filter_units_by_property CanStart yes $(
+                          __systemctl $mode list-unit-files --state enabled,disabled,static | \
+                               { while read -r a b; do [[ $a =~ @\. ]] || echo -E - " $a"; done; }
+                          __systemctl $mode list-units --state inactive,failed | \
+                               { while read -r a b; do echo -E - " $a"; done; } )))
+}
+
+_systemctl_restartable_units(){
+    _sys_restartable_units=(_filter_units_by_property CanStart yes $(
+                          __systemctl $mode list-unit-files --state enabled,disabled,static | \
+                               { while read -r a b; do [[ $a =~ @\. ]] || echo -E - " $a"; done; }
+                          __systemctl $mode list-units | \
+                               { while read -r a b; do echo -E - " $a"; done; } ))
+}
+
 _systemctl_failed_units()  {_sys_failed_units=(  $(__systemctl list-units --failed | { while read -r a b; do echo -E - " $a"; done; }) )}
 _systemctl_enabled_units() {_sys_enabled_units=( $(__systemctl list-unit-files     | { while read -r a b; do [[ $b == "enabled" ]] && echo -E - " $a"; done; }) )}
 _systemctl_disabled_units(){_sys_disabled_units=($(__systemctl list-unit-files     | { while read -r a b; do [[ $b == "disabled" ]] && echo -E - " $a"; done; }) )}
@@ -155,20 +179,24 @@
 done
 
 # Completion functions for ENABLED_UNITS
-for fun in disable reenable ; do
-  (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
-  {
+(( $+functions[_systemctl_disable] )) || _systemctl_disable()
+{
+    _systemctl_enabled_units
+    compadd "$@" -a - _sys_enabled_units
+}
+
+(( $+functions[_systemctl_reenable] )) || _systemctl_reenable()
+{
     _systemctl_enabled_units
     _systemctl_disabled_units
-    compadd "$@" -a - _sys_enabled_units _sys_disabled_units
-  }
-done
+    compadd "$@" -a - _sys_enabled_units _sys_disabled_units $(_systemctl_get_template_names)
+}
 
 # Completion functions for DISABLED_UNITS
 (( $+functions[_systemctl_enable] )) || _systemctl_enable()
 {
   _systemctl_disabled_units
-  compadd "$@" -a - _sys_disabled_units
+  compadd "$@" -a - _sys_disabled_units $(_systemctl_get_template_names)
 }
 
 # Completion functions for FAILED_UNITS
@@ -181,8 +209,8 @@
 # Completion functions for STARTABLE_UNITS
 (( $+functions[_systemctl_start] )) || _systemctl_start()
 {
-  _systemctl_inactive_units
-  compadd "$@" -a - _sys_inactive_units
+   _systemctl_startable_units
+   compadd "$@" - ${_sys_startable_units[*]} $(_systemctl_get_template_names)
 }
 
 # Completion functions for STOPPABLE_UNITS
@@ -217,11 +245,8 @@
 for fun in restart reload-or-restart ; do
   (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
   {
-    _systemctl_all_units
-    compadd "$@" - $( _filter_units_by_property CanStart yes \
-      ${_sys_all_units[*]} | while read -r line; do \
-      [[ "$line" =~ \.device$ ]] || echo -E - " $line"; \
-      done )
+    _systemctl_restartable_units
+    compadd "$@" - ${_sys_restartable_units[*]} $(_systemctl_get_template_names)
   }
 done
 
@@ -229,21 +254,28 @@
 (( $+functions[_systemctl_unmask] )) || _systemctl_unmask()
 {
   _systemctl_masked_units
-  compadd "$@" -a - _sys_masked_units || _message "no masked unit found"
+  compadd "$@" -a - _sys_masked_units || _message "no masked units found"
 }
 
 # Completion functions for JOBS
 (( $+functions[_systemctl_cancel] )) || _systemctl_cancel()
 {
   compadd "$@" - $(__systemctl list-jobs \
-    | cut -d' ' -f1  2>/dev/null ) || _message "no job found"
+    | cut -d' ' -f1  2>/dev/null ) || _message "no jobs found"
 }
 
 # Completion functions for SNAPSHOTS
 (( $+functions[_systemctl_delete] )) || _systemctl_delete()
 {
   compadd "$@" - $(__systemctl list-units --type snapshot --all \
-    | cut -d' ' -f1  2>/dev/null ) || _message "no snapshot found"
+    | cut -d' ' -f1  2>/dev/null ) || _message "no snapshots found"
+}
+
+# Completion functions for TARGETS
+(( $+functions[_systemctl_set-default] )) || _systemctl_set-default()
+{
+  compadd "$@" - $(__systemctl list-unit-files --type target --all \
+    | cut -d' ' -f1  2>/dev/null ) || _message "no targets found"
 }
 
 # Completion functions for ENVS
diff -urN systemd-216/src/bus-proxyd/bus-proxyd.c systemd-217/src/bus-proxyd/bus-proxyd.c
--- systemd-216/src/bus-proxyd/bus-proxyd.c	2014-11-03 09:35:36.603263971 -0800
+++ systemd-217/src/bus-proxyd/bus-proxyd.c	2014-10-24 10:28:55.293169106 -0700
@@ -186,7 +186,7 @@
         assert(a);
         assert(b);
 
-        r = sd_bus_get_peer_creds(b, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_COMM, &creds);
+        r = sd_bus_get_owner_creds(b, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_COMM, &creds);
         if (r < 0)
                 return r;
 
@@ -454,7 +454,7 @@
 
         assert_return(service_name_is_valid(name), -EINVAL);
 
-        r = sd_bus_get_owner(bus, name, mask, &c);
+        r = sd_bus_get_name_creds(bus, name, mask, &c);
         if (r == -ESRCH || r == -ENXIO)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Name %s is currently not owned by anyone.", name);
         if (r < 0)
@@ -644,28 +644,31 @@
 
         } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionSELinuxSecurityContext")) {
                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
 
-                r = get_creds_by_message(a, m, SD_BUS_CREDS_SELINUX_CONTEXT, &creds, NULL);
+                r = get_creds_by_message(a, m, SD_BUS_CREDS_SELINUX_CONTEXT, &creds, &error);
                 if (r < 0)
-                        return synthetic_reply_method_errno(m, r, NULL);
+                        return synthetic_reply_method_errno(m, r, &error);
 
                 return synthetic_reply_method_return(m, "y", creds->label, strlen(creds->label));
 
         } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionUnixProcessID")) {
                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
 
-                r = get_creds_by_message(a, m, SD_BUS_CREDS_PID, &creds, NULL);
+                r = get_creds_by_message(a, m, SD_BUS_CREDS_PID, &creds, &error);
                 if (r < 0)
-                        return synthetic_reply_method_errno(m, r, NULL);
+                        return synthetic_reply_method_errno(m, r, &error);
 
                 return synthetic_reply_method_return(m, "u", (uint32_t) creds->pid);
 
         } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionUnixUser")) {
                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
 
-                r = get_creds_by_message(a, m, SD_BUS_CREDS_UID, &creds, NULL);
+                r = get_creds_by_message(a, m, SD_BUS_CREDS_UID, &creds, &error);
                 if (r < 0)
-                        return synthetic_reply_method_errno(m, r, NULL);
+                        return synthetic_reply_method_errno(m, r, &error);
 
                 return synthetic_reply_method_return(m, "u", (uint32_t) creds->uid);
 
@@ -731,8 +734,9 @@
                 struct kdbus_cmd_name_list cmd = {};
                 struct kdbus_name_list *name_list;
                 struct kdbus_cmd_free cmd_free;
-                struct kdbus_cmd_name *name;
+                struct kdbus_name_info *name;
                 _cleanup_strv_free_ char **owners = NULL;
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
                 char *arg0;
                 int err = 0;
 
@@ -743,6 +747,14 @@
                 if (!service_name_is_valid(arg0))
                         return synthetic_reply_method_errno(m, -EINVAL, NULL);
 
+                r = sd_bus_get_name_creds(a, arg0, 0, NULL);
+                if (r == -ESRCH || r == -ENXIO) {
+                        sd_bus_error_setf(&error, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Could not get owners of name '%s': no such name.", arg0);
+                        return synthetic_reply_method_errno(m, r, &error);
+                }
+                if (r < 0)
+                        return synthetic_reply_method_errno(m, r, NULL);
+
                 cmd.flags = KDBUS_NAME_LIST_QUEUED;
                 r = ioctl(a->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
                 if (r < 0)
@@ -799,7 +811,7 @@
                 if (streq(name, "org.freedesktop.DBus"))
                         return synthetic_reply_method_return(m, "b", true);
 
-                r = sd_bus_get_owner(a, name, 0, NULL);
+                r = sd_bus_get_name_creds(a, name, 0, NULL);
                 if (r < 0 && r != -ESRCH && r != -ENXIO)
                         return synthetic_reply_method_errno(m, r, NULL);
 
@@ -836,7 +848,7 @@
 
         } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "RequestName")) {
                 const char *name;
-                uint32_t flags;
+                uint32_t flags, param;
 
                 r = sd_bus_message_read(m, "su", &name, &flags);
                 if (r < 0)
@@ -847,7 +859,15 @@
                 if ((flags & ~(BUS_NAME_ALLOW_REPLACEMENT|BUS_NAME_REPLACE_EXISTING|BUS_NAME_DO_NOT_QUEUE)) != 0)
                         return synthetic_reply_method_errno(m, -EINVAL, NULL);
 
-                r = sd_bus_request_name(a, name, flags);
+                param = 0;
+                if (flags & BUS_NAME_ALLOW_REPLACEMENT)
+                        param |= SD_BUS_NAME_ALLOW_REPLACEMENT;
+                if (flags & BUS_NAME_REPLACE_EXISTING)
+                        param |= SD_BUS_NAME_REPLACE_EXISTING;
+                if (!(flags & BUS_NAME_DO_NOT_QUEUE))
+                        param |= SD_BUS_NAME_QUEUE;
+
+                r = sd_bus_request_name(a, name, param);
                 if (r < 0) {
                         if (r == -EEXIST)
                                 return synthetic_reply_method_return(m, "u", BUS_NAME_EXISTS);
@@ -875,7 +895,7 @@
                 if (flags != 0)
                         return synthetic_reply_method_errno(m, -EINVAL, NULL);
 
-                r = sd_bus_get_owner(a, name, 0, NULL);
+                r = sd_bus_get_name_creds(a, name, 0, NULL);
                 if (r >= 0 || streq(name, "org.freedesktop.DBus"))
                         return synthetic_reply_method_return(m, "u", BUS_START_REPLY_ALREADY_RUNNING);
                 if (r != -ESRCH)
@@ -1146,12 +1166,7 @@
                 sd_is_socket(out_fd, AF_UNIX, 0, 0) > 0;
 
         if (is_unix) {
-                r = getpeercred(in_fd, &ucred);
-                if (r < 0) {
-                        log_error("Failed to get peer creds: %s", strerror(-r));
-                        goto finish;
-                }
-
+                (void) getpeercred(in_fd, &ucred);
                 (void) getpeersec(in_fd, &peersec);
         }
 
diff -urN systemd-216/src/cgtop/cgtop.c systemd-217/src/cgtop/cgtop.c
--- systemd-216/src/cgtop/cgtop.c	2014-11-03 09:35:27.849175703 -0800
+++ systemd-217/src/cgtop/cgtop.c	2014-10-23 10:00:37.299180368 -0700
@@ -126,7 +126,9 @@
                                 return r;
                         }
                 } else {
-                        assert_se(hashmap_move_one(a, b, path) == 0);
+                        r = hashmap_move_one(a, b, path);
+                        if (r < 0)
+                                return r;
                         g->cpu_valid = g->memory_valid = g->io_valid = g->n_tasks_valid = false;
                 }
         }
diff -urN systemd-216/src/console/consoled-manager.c systemd-217/src/console/consoled-manager.c
--- systemd-216/src/console/consoled-manager.c	2014-11-03 09:35:34.745245236 -0800
+++ systemd-217/src/console/consoled-manager.c	2014-10-28 04:27:00.425284409 -0700
@@ -132,7 +132,7 @@
         if (r < 0)
                 return 0;
 
-        return streq(desktop, "SYSTEMD-CONSOLE");
+        return streq(desktop, "systemd-console");
 }
 
 static int manager_sysview_session_add(Manager *m, sysview_event *event) {
diff -urN systemd-216/src/core/condition.c systemd-217/src/core/condition.c
--- systemd-216/src/core/condition.c	2014-07-07 10:18:24.860662644 -0700
+++ systemd-217/src/core/condition.c	2014-10-23 08:23:16.468728788 -0700
@@ -45,13 +45,13 @@
         assert(c->type == CONDITION_SECURITY);
 
         if (streq(c->parameter, "selinux"))
-                return use_selinux() == !c->negate;
+                return mac_selinux_use() == !c->negate;
+        if (streq(c->parameter, "smack"))
+                return mac_smack_use() == !c->negate;
         if (streq(c->parameter, "apparmor"))
-                return use_apparmor() == !c->negate;
+                return mac_apparmor_use() == !c->negate;
         if (streq(c->parameter, "ima"))
                 return use_ima() == !c->negate;
-        if (streq(c->parameter, "smack"))
-                return use_smack() == !c->negate;
 
         return c->negate;
 }
diff -urN systemd-216/src/core/dbus.c systemd-217/src/core/dbus.c
--- systemd-216/src/core/dbus.c	2014-11-03 09:35:27.850175713 -0800
+++ systemd-217/src/core/dbus.c	2014-10-28 06:31:48.701077422 -0700
@@ -211,7 +211,7 @@
 }
 
 #ifdef HAVE_SELINUX
-static int selinux_filter(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+static int mac_selinux_filter(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
         Manager *m = userdata;
         const char *verb, *path;
         Unit *u = NULL;
@@ -239,7 +239,7 @@
 
         if (object_path_startswith("/org/freedesktop/systemd1", path)) {
 
-                r = selinux_access_check(message, verb, error);
+                r = mac_selinux_access_check(message, verb, error);
                 if (r < 0)
                         return r;
 
@@ -270,7 +270,7 @@
         if (!u)
                 return 0;
 
-        r = selinux_unit_access_check(u, message, verb, error);
+        r = mac_selinux_unit_access_check(u, message, verb, error);
         if (r < 0)
                 return r;
 
@@ -536,7 +536,7 @@
         assert(bus);
 
 #ifdef HAVE_SELINUX
-        r = sd_bus_add_filter(bus, NULL, selinux_filter, m);
+        r = sd_bus_add_filter(bus, NULL, mac_selinux_filter, m);
         if (r < 0) {
                 log_error("Failed to add SELinux access filter: %s", strerror(-r));
                 return r;
diff -urN systemd-216/src/core/dbus-job.c systemd-217/src/core/dbus-job.c
--- systemd-216/src/core/dbus-job.c	2014-08-19 15:18:14.112415925 -0700
+++ systemd-217/src/core/dbus-job.c	2014-10-28 06:31:48.699077426 -0700
@@ -80,7 +80,7 @@
         if (r < 0)
                 return r;
 
-        r = selinux_unit_access_check(j->unit, message, "stop", error);
+        r = mac_selinux_unit_access_check(j->unit, message, "stop", error);
         if (r < 0)
                 return r;
 
diff -urN systemd-216/src/core/dbus-manager.c systemd-217/src/core/dbus-manager.c
--- systemd-216/src/core/dbus-manager.c	2014-11-03 09:35:36.031258203 -0800
+++ systemd-217/src/core/dbus-manager.c	2014-10-28 06:31:48.699077426 -0700
@@ -363,7 +363,7 @@
         if (!u)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
 
-        r = selinux_unit_access_check(u, message, "status", error);
+        r = mac_selinux_unit_access_check(u, message, "status", error);
         if (r < 0)
                 return r;
 
@@ -409,7 +409,7 @@
         if (!u)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
 
-        r = selinux_unit_access_check(u, message, "status", error);
+        r = mac_selinux_unit_access_check(u, message, "status", error);
         if (r < 0)
                 return r;
 
@@ -441,7 +441,7 @@
         if (r < 0)
                 return r;
 
-        r = selinux_unit_access_check(u, message, "status", error);
+        r = mac_selinux_unit_access_check(u, message, "status", error);
         if (r < 0)
                 return r;
 
@@ -648,7 +648,7 @@
         if (mode < 0)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
 
-        r = selinux_access_check(message, "start", error);
+        r = mac_selinux_access_check(message, "start", error);
         if (r < 0)
                 return r;
 
@@ -702,7 +702,7 @@
         if (!j)
                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
 
-        r = selinux_unit_access_check(j->unit, message, "status", error);
+        r = mac_selinux_unit_access_check(j->unit, message, "status", error);
         if (r < 0)
                 return r;
 
@@ -742,7 +742,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "reboot", error);
+        r = mac_selinux_access_check(message, "reboot", error);
         if (r < 0)
                 return r;
 
@@ -759,7 +759,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "reload", error);
+        r = mac_selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -782,7 +782,7 @@
 
         /* Anyone can call this method */
 
-        r = selinux_access_check(message, "status", error);
+        r = mac_selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -870,7 +870,7 @@
 
         /* Anyone can call this method */
 
-        r = selinux_access_check(message, "status", error);
+        r = mac_selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -922,7 +922,7 @@
 
         /* Anyone can call this method */
 
-        r = selinux_access_check(message, "status", error);
+        r = mac_selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -957,7 +957,7 @@
 
         /* Anyone can call this method */
 
-        r = selinux_access_check(message, "status", error);
+        r = mac_selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -985,7 +985,7 @@
 
         /* Anyone can call this method */
 
-        r = selinux_access_check(message, "status", error);
+        r = mac_selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -1016,7 +1016,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "start", error);
+        r = mac_selinux_access_check(message, "start", error);
         if (r < 0)
                 return r;
 
@@ -1048,7 +1048,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "stop", error);
+        r = mac_selinux_access_check(message, "stop", error);
         if (r < 0)
                 return r;
 
@@ -1080,7 +1080,7 @@
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
-        r = selinux_access_check(message, "reload", error);
+        r = mac_selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1114,7 +1114,7 @@
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
-        r = selinux_access_check(message, "reload", error);
+        r = mac_selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1133,7 +1133,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "halt", error);
+        r = mac_selinux_access_check(message, "halt", error);
         if (r < 0)
                 return r;
 
@@ -1153,7 +1153,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "reboot", error);
+        r = mac_selinux_access_check(message, "reboot", error);
         if (r < 0)
                 return r;
 
@@ -1174,7 +1174,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "halt", error);
+        r = mac_selinux_access_check(message, "halt", error);
         if (r < 0)
                 return r;
 
@@ -1194,7 +1194,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "halt", error);
+        r = mac_selinux_access_check(message, "halt", error);
         if (r < 0)
                 return r;
 
@@ -1214,7 +1214,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "reboot", error);
+        r = mac_selinux_access_check(message, "reboot", error);
         if (r < 0)
                 return r;
 
@@ -1236,7 +1236,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "reboot", error);
+        r = mac_selinux_access_check(message, "reboot", error);
         if (r < 0)
                 return r;
 
@@ -1300,7 +1300,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "reload", error);
+        r = mac_selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1326,7 +1326,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "reload", error);
+        r = mac_selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1353,7 +1353,7 @@
         assert(message);
         assert(m);
 
-        r = selinux_access_check(message, "reload", error);
+        r = mac_selinux_access_check(message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -1391,7 +1391,7 @@
 
         /* Anyone can call this method */
 
-        r = selinux_access_check(message, "status", error);
+        r = mac_selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -1444,7 +1444,7 @@
 
         /* Anyone can call this method */
 
-        r = selinux_access_check(message, "status", error);
+        r = mac_selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -1473,7 +1473,7 @@
 
         /* Anyone can call this method */
 
-        r = selinux_access_check(message, "status", error);
+        r = mac_selinux_access_check(message, "status", error);
         if (r < 0)
                 return r;
 
@@ -1585,7 +1585,7 @@
         if (r < 0)
                 return r;
 
-        r = selinux_unit_access_check_strv(l, message, m, verb, error);
+        r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
         if (r < 0)
                 return r;
 
@@ -1659,7 +1659,7 @@
                         return -EINVAL;
         }
 
-        r = selinux_unit_access_check_strv(l, message, m, "enable", error);
+        r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
         if (r < 0)
                 return r;
 
@@ -1696,7 +1696,7 @@
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
-        r = selinux_access_check(message, verb, error);
+        r = mac_selinux_access_check(message, verb, error);
         if (r < 0)
                 return r;
 
@@ -1743,7 +1743,7 @@
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
-        r = selinux_access_check(message, "enable", error);
+        r = mac_selinux_access_check(message, "enable", error);
         if (r < 0)
                 return r;
 
@@ -1779,7 +1779,7 @@
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
-        r = selinux_access_check(message, "enable", error);
+        r = mac_selinux_access_check(message, "enable", error);
         if (r < 0)
                 return r;
 
@@ -1837,7 +1837,7 @@
         if (dep < 0)
                 return -EINVAL;
 
-        r = selinux_unit_access_check_strv(l, message, m, "enable", error);
+        r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
         if (r < 0)
                 return r;
 
diff -urN systemd-216/src/core/dbus-snapshot.c systemd-217/src/core/dbus-snapshot.c
--- systemd-216/src/core/dbus-snapshot.c	2014-05-14 13:58:43.367849011 -0700
+++ systemd-217/src/core/dbus-snapshot.c	2014-10-28 06:31:48.700077424 -0700
@@ -33,7 +33,7 @@
         assert(message);
         assert(s);
 
-        r = selinux_unit_access_check(UNIT(s), message, "stop", error);
+        r = mac_selinux_unit_access_check(UNIT(s), message, "stop", error);
         if (r < 0)
                 return r;
 
diff -urN systemd-216/src/core/dbus-swap.c systemd-217/src/core/dbus-swap.c
--- systemd-216/src/core/dbus-swap.c	2014-11-03 09:35:32.631223921 -0800
+++ systemd-217/src/core/dbus-swap.c	2014-10-28 06:31:25.184131420 -0700
@@ -55,7 +55,7 @@
         return sd_bus_message_append(reply, "i", p);
 }
 
-static int property_get_discard(
+static int property_get_options(
                 sd_bus *bus,
                 const char *path,
                 const char *interface,
@@ -65,17 +65,16 @@
                 sd_bus_error *error) {
 
         Swap *s = SWAP(userdata);
-        const char *p;
+        const char *options = NULL;
 
         assert(bus);
         assert(reply);
         assert(s);
 
         if (s->from_fragment)
-                p = s->parameters_fragment.discard ?: "none";
-        else
-                p = "none";
-        return sd_bus_message_append(reply, "s", p);
+                options = s->parameters_fragment.options;
+
+        return sd_bus_message_append(reply, "s", options);
 }
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, swap_result, SwapResult);
@@ -84,7 +83,7 @@
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("What", "s", NULL, offsetof(Swap, what), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Priority", "i", property_get_priority, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("Discard", "s", property_get_discard, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("Options", "s", property_get_options, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("TimeoutUSec", "t", bus_property_get_usec, offsetof(Swap, timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Swap, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Swap, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
diff -urN systemd-216/src/core/dbus-unit.c systemd-217/src/core/dbus-unit.c
--- systemd-216/src/core/dbus-unit.c	2014-08-18 09:11:26.884137010 -0700
+++ systemd-217/src/core/dbus-unit.c	2014-10-28 06:31:48.701077422 -0700
@@ -33,6 +33,7 @@
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_job_mode, job_mode, JobMode);
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_failure_action, failure_action, FailureAction);
 
 static int property_get_names(
                 sd_bus *bus,
@@ -442,7 +443,7 @@
         if (signo <= 0 || signo >= _NSIG)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range.");
 
-        r = selinux_unit_access_check(u, message, "stop", error);
+        r = mac_selinux_unit_access_check(u, message, "stop", error);
         if (r < 0)
                 return r;
 
@@ -467,7 +468,7 @@
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
-        r = selinux_unit_access_check(u, message, "reload", error);
+        r = mac_selinux_unit_access_check(u, message, "reload", error);
         if (r < 0)
                 return r;
 
@@ -494,7 +495,7 @@
         if (r < 0)
                 return r;
 
-        r = selinux_unit_access_check(u, message, "start", error);
+        r = mac_selinux_unit_access_check(u, message, "start", error);
         if (r < 0)
                 return r;
 
@@ -562,6 +563,8 @@
         SD_BUS_PROPERTY("IgnoreOnSnapshot", "b", bus_property_get_bool, offsetof(Unit, ignore_on_snapshot), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("JobTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("JobTimeoutAction", "s", property_get_failure_action, offsetof(Unit, job_timeout_action), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("JobTimeoutRebootArgument", "s", NULL, offsetof(Unit, job_timeout_reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ConditionResult", "b", bus_property_get_bool, offsetof(Unit, condition_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         BUS_PROPERTY_DUAL_TIMESTAMP("ConditionTimestamp", offsetof(Unit, condition_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Conditions", "a(sbbsi)", property_get_conditions, 0, 0),
@@ -754,7 +757,7 @@
                         type = JOB_RELOAD;
         }
 
-        r = selinux_unit_access_check(
+        r = mac_selinux_unit_access_check(
                         u, message,
                         (type == JOB_START || type == JOB_RESTART || type == JOB_TRY_RESTART) ? "start" :
                         type == JOB_STOP ? "stop" : "reload", error);
diff -urN systemd-216/src/core/execute.c systemd-217/src/core/execute.c
--- systemd-216/src/core/execute.c	2014-11-03 09:35:32.812225745 -0800
+++ systemd-217/src/core/execute.c	2014-10-23 08:25:39.892261063 -0700
@@ -1545,7 +1545,10 @@
                                 context->protect_home,
                                 context->protect_system,
                                 context->mount_flags);
-                if (err < 0) {
+
+                if (err == -EPERM)
+                        log_warning_unit(params->unit_id, "Failed to set up file system namespace due to lack of privileges. Execution sandbox will not be in effect: %s", strerror(-err));
+                else if (err < 0) {
                         *error = EXIT_NAMESPACE;
                         return err;
                 }
@@ -1666,7 +1669,7 @@
 #endif
 
 #ifdef HAVE_SELINUX
-                if (use_selinux()) {
+                if (mac_selinux_use()) {
                         if (context->selinux_context) {
                                 err = setexeccon(context->selinux_context);
                                 if (err < 0 && !context->selinux_context_ignore) {
@@ -1678,7 +1681,7 @@
                         if (params->selinux_context_net && socket_fd >= 0) {
                                 _cleanup_free_ char *label = NULL;
 
-                                err = label_get_child_mls_label(socket_fd, command->path, &label);
+                                err = mac_selinux_get_child_mls_label(socket_fd, command->path, &label);
                                 if (err < 0) {
                                         *error = EXIT_SELINUX_CONTEXT;
                                         return err;
@@ -1694,11 +1697,11 @@
 #endif
 
 #ifdef HAVE_APPARMOR
-                if (context->apparmor_profile && use_apparmor()) {
+                if (context->apparmor_profile && mac_apparmor_use()) {
                         err = aa_change_onexec(context->apparmor_profile);
                         if (err < 0 && !context->apparmor_profile_ignore) {
                                 *error = EXIT_APPARMOR_PROFILE;
-                                return err;
+                                return -errno;
                         }
                 }
 #endif
@@ -1782,7 +1785,7 @@
                 n_fds = params->n_fds;
         }
 
-        err = exec_context_load_environment(context, &files_env);
+        err = exec_context_load_environment(context, params->unit_id, &files_env);
         if (err < 0) {
                 log_struct_unit(LOG_ERR,
                            params->unit_id,
@@ -2011,7 +2014,7 @@
         }
 }
 
-int exec_context_load_environment(const ExecContext *c, char ***l) {
+int exec_context_load_environment(const ExecContext *c, const char *unit_id, char ***l) {
         char **i, **r = NULL;
 
         assert(c);
@@ -2068,7 +2071,7 @@
                         }
                         /* Log invalid environment variables with filename */
                         if (p)
-                                p = strv_env_clean_log(p, pglob.gl_pathv[n]);
+                                p = strv_env_clean_log(p, unit_id, pglob.gl_pathv[n]);
 
                         if (r == NULL)
                                 r = p;
diff -urN systemd-216/src/core/execute.h systemd-217/src/core/execute.h
--- systemd-216/src/core/execute.h	2014-11-03 09:35:32.544223043 -0800
+++ systemd-217/src/core/execute.h	2014-10-20 10:23:13.441878951 -0700
@@ -241,7 +241,7 @@
 
 int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_root);
 
-int exec_context_load_environment(const ExecContext *c, char ***l);
+int exec_context_load_environment(const ExecContext *c, const char *unit_id, char ***l);
 
 bool exec_context_may_touch_console(ExecContext *c);
 
diff -urN systemd-216/src/core/failure-action.c systemd-217/src/core/failure-action.c
--- systemd-216/src/core/failure-action.c	2014-11-03 09:35:22.037117100 -0800
+++ systemd-217/src/core/failure-action.c	2014-10-28 09:25:51.557723299 -0700
@@ -29,6 +29,13 @@
 #include "special.h"
 #include "failure-action.h"
 
+static void log_and_status(Manager *m, const char *message) {
+        log_warning("%s", message);
+        manager_status_printf(m, STATUS_TYPE_EMERGENCY,
+                              ANSI_HIGHLIGHT_RED_ON " !!  " ANSI_HIGHLIGHT_OFF,
+                              "%s", message);
+}
+
 int failure_action(
                 Manager *m,
                 FailureAction action,
@@ -57,7 +64,7 @@
         case FAILURE_ACTION_REBOOT: {
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
 
-                log_warning("Rebooting as result of failure.");
+                log_and_status(m, "Rebooting as result of failure.");
 
                 update_reboot_param_file(reboot_arg);
                 r = manager_add_job_by_name(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE, true, &error, NULL);
@@ -68,13 +75,14 @@
         }
 
         case FAILURE_ACTION_REBOOT_FORCE:
-                log_warning("Forcibly rebooting as result of failure.");
+                log_and_status(m, "Forcibly rebooting as result of failure.");
+
                 update_reboot_param_file(reboot_arg);
                 m->exit_code = MANAGER_REBOOT;
                 break;
 
         case FAILURE_ACTION_REBOOT_IMMEDIATE:
-                log_warning("Rebooting immediately as result of failure.");
+                log_and_status(m, "Rebooting immediately as result of failure.");
 
                 sync();
 
@@ -90,7 +98,7 @@
         case FAILURE_ACTION_POWEROFF: {
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
 
-                log_warning("Powering off as result of failure.");
+                log_and_status(m, "Powering off as result of failure.");
 
                 r = manager_add_job_by_name(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE, true, &error, NULL);
                 if (r < 0)
@@ -100,12 +108,12 @@
         }
 
         case FAILURE_ACTION_POWEROFF_FORCE:
-                log_warning("Forcibly powering off as result of failure.");
+                log_and_status(m, "Forcibly powering off as result of failure.");
                 m->exit_code = MANAGER_POWEROFF;
                 break;
 
         case FAILURE_ACTION_POWEROFF_IMMEDIATE:
-                log_warning("Powering off immediately as result of failure.");
+                log_and_status(m, "Powering off immediately as result of failure.");
 
                 sync();
 
diff -urN systemd-216/src/core/hostname-setup.c systemd-217/src/core/hostname-setup.c
--- systemd-216/src/core/hostname-setup.c	2014-03-18 10:05:49.609378369 -0700
+++ systemd-217/src/core/hostname-setup.c	2014-10-27 04:48:29.291966279 -0700
@@ -82,7 +82,7 @@
                 hn = "localhost";
         }
 
-        if (sethostname(hn, strlen(hn)) < 0) {
+        if (sethostname_idempotent(hn) < 0) {
                 log_warning("Failed to set hostname to <%s>: %m", hn);
                 return -errno;
         }
diff -urN systemd-216/src/core/job.c systemd-217/src/core/job.c
--- systemd-216/src/core/job.c	2014-11-03 09:35:24.668143629 -0800
+++ systemd-217/src/core/job.c	2014-10-28 09:25:51.558723288 -0700
@@ -639,7 +639,7 @@
 
                         manager_flip_auto_status(u->manager, true);
                         unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format);
-                        manager_status_printf(u->manager, false, NULL,
+                        manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL,
                                               "See \"systemctl status %s%s%s\" for details.",
                                               quotes ? "'" : "", u->id, quotes ? "'" : "");
                         break;
@@ -858,14 +858,18 @@
 
 static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *userdata) {
         Job *j = userdata;
+        Unit *u;
 
         assert(j);
         assert(s == j->timer_event_source);
 
-        log_warning_unit(j->unit->id, "Job %s/%s timed out.",
-                         j->unit->id, job_type_to_string(j->type));
+        log_warning_unit(j->unit->id, "Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
 
+        u = j->unit;
         job_finish_and_invalidate(j, JOB_TIMEOUT, true);
+
+        failure_action(u->manager, u->job_timeout_action, u->job_timeout_reboot_arg);
+
         return 0;
 }
 
diff -urN systemd-216/src/core/load-fragment.c systemd-217/src/core/load-fragment.c
--- systemd-216/src/core/load-fragment.c	2014-11-03 09:35:27.851175723 -0800
+++ systemd-217/src/core/load-fragment.c	2014-10-24 09:31:53.444566285 -0700
@@ -288,7 +288,8 @@
                                void *data,
                                void *userdata) {
 
-        SocketPort *p, *tail;
+        _cleanup_free_ SocketPort *p = NULL;
+        SocketPort *tail;
         Socket *s;
         int r;
 
@@ -315,10 +316,9 @@
                 r = unit_full_printf(UNIT(s), rvalue, &p->path);
                 if (r < 0) {
                         p->path = strdup(rvalue);
-                        if (!p->path) {
-                                free(p);
+                        if (!p->path)
                                 return log_oom();
-                        } else
+                        else
                                 log_syntax(unit, LOG_ERR, filename, line, -r,
                                            "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r));
                 }
@@ -334,11 +334,10 @@
                         log_syntax(unit, LOG_ERR, filename, line, -r,
                                    "Failed to resolve unit specifiers on %s, ignoring: %s", rvalue, strerror(-r));
 
-                r = socket_address_parse_netlink(&p->address, k ? k : rvalue);
+                r = socket_address_parse_netlink(&p->address, k ?: rvalue);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, -r,
                                    "Failed to parse address value, ignoring: %s", rvalue);
-                        free(p);
                         return 0;
                 }
 
@@ -355,7 +354,6 @@
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, -r,
                                    "Failed to parse address value, ignoring: %s", rvalue);
-                        free(p);
                         return 0;
                 }
 
@@ -371,7 +369,6 @@
                 if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) {
                         log_syntax(unit, LOG_ERR, filename, line, ENOTSUP,
                                    "Address family not supported, ignoring: %s", rvalue);
-                        free(p);
                         return 0;
                 }
         }
@@ -384,6 +381,7 @@
                 LIST_INSERT_AFTER(port, s->ports, tail, p);
         } else
                 LIST_PREPEND(port, s->ports, p);
+        p = NULL;
 
         return 0;
 }
@@ -1368,8 +1366,7 @@
 
         v = new0(TimerValue, 1);
         if (!v) {
-                if (c)
-                        calendar_spec_free(c);
+                calendar_spec_free(c);
                 return log_oom();
         }
 
diff -urN systemd-216/src/core/load-fragment-gperf.gperf.m4 systemd-217/src/core/load-fragment-gperf.gperf.m4
--- systemd-216/src/core/load-fragment-gperf.gperf.m4	2014-11-03 09:35:32.544223043 -0800
+++ systemd-217/src/core/load-fragment-gperf.gperf.m4	2014-10-28 06:31:25.184131420 -0700
@@ -152,6 +152,8 @@
 Unit.IgnoreOnIsolate,            config_parse_bool,                  0,                             offsetof(Unit, ignore_on_isolate)
 Unit.IgnoreOnSnapshot,           config_parse_bool,                  0,                             offsetof(Unit, ignore_on_snapshot)
 Unit.JobTimeoutSec,              config_parse_sec,                   0,                             offsetof(Unit, job_timeout)
+Unit.JobTimeoutAction,           config_parse_failure_action,        0,                             offsetof(Unit, job_timeout_action)
+Unit.JobTimeoutRebootArgument,   config_parse_string,                0,                             offsetof(Unit, job_timeout_reboot_arg)
 Unit.ConditionPathExists,        config_parse_unit_condition_path,   CONDITION_PATH_EXISTS,         0
 Unit.ConditionPathExistsGlob,    config_parse_unit_condition_path,   CONDITION_PATH_EXISTS_GLOB,    0
 Unit.ConditionPathIsDirectory,   config_parse_unit_condition_path,   CONDITION_PATH_IS_DIRECTORY,   0
@@ -297,7 +299,7 @@
 m4_dnl
 Swap.What,                       config_parse_path,                  0,                             offsetof(Swap, parameters_fragment.what)
 Swap.Priority,                   config_parse_int,                   0,                             offsetof(Swap, parameters_fragment.priority)
-Swap.Discard,                    config_parse_string,                0,                             offsetof(Swap, parameters_fragment.discard)
+Swap.Options,                    config_parse_string,                0,                             offsetof(Swap, parameters_fragment.options)
 Swap.TimeoutSec,                 config_parse_sec,                   0,                             offsetof(Swap, timeout_usec)
 EXEC_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
 CGROUP_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
diff -urN systemd-216/src/core/machine-id-setup.c systemd-217/src/core/machine-id-setup.c
--- systemd-216/src/core/machine-id-setup.c	2014-11-03 09:35:20.952106160 -0800
+++ systemd-217/src/core/machine-id-setup.c	2014-11-03 09:33:49.083179846 -0800
@@ -162,7 +162,7 @@
 int machine_id_setup(const char *root) {
         const char *etc_machine_id, *run_machine_id;
         _cleanup_close_ int fd = -1;
-        bool writable = false;
+        bool writable = true;
         struct stat st;
         char id[34]; /* 32 + \n + \0 */
         int r;
@@ -186,12 +186,19 @@
 
                 mkdir_parents(etc_machine_id, 0755);
                 fd = open(etc_machine_id, O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444);
-                if (fd >= 0)
-                        writable = true;
-                else {
+                if (fd < 0) {
+                        int old_errno = errno;
+
                         fd = open(etc_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY);
                         if (fd < 0) {
-                                log_error("Cannot open %s: %m", etc_machine_id);
+                                if (old_errno == EROFS && errno == ENOENT)
+                                        log_error("System cannot boot: Missing /etc/machine-id and /etc is mounted read-only.\n"
+                                                  "Booting up is supported only when:\n"
+                                                  "1) /etc/machine-id exists and is populated.\n"
+                                                  "2) /etc/machine-id exists and is empty.\n"
+                                                  "3) /etc/machine-id is missing and /etc is writable.\n");
+                                else
+                                        log_error("Cannot open %s: %m", etc_machine_id);
                                 return -errno;
                         }
 
diff -urN systemd-216/src/core/macros.systemd.in systemd-217/src/core/macros.systemd.in
--- systemd-216/src/core/macros.systemd.in	2014-08-18 17:15:46.062623339 -0700
+++ systemd-217/src/core/macros.systemd.in	2014-10-28 04:23:14.062133565 -0700
@@ -43,6 +43,8 @@
 fi \
 %{nil}
 
+%systemd_user_post() %systemd_post --user --global %{?*}
+
 %systemd_preun() \
 if [ $1 -eq 0 ] ; then \
         # Package removal, not upgrade \
@@ -51,10 +53,19 @@
 fi \
 %{nil}
 
+%systemd_user_preun() \
+if [ $1 -eq 0 ] ; then \
+        # Package removal, not upgrade \
+        systemctl --no-reload --user --global disable %{?*} > /dev/null 2>&1 || : \
+fi \
+%{nil}
+
 %systemd_postun() \
 systemctl daemon-reload >/dev/null 2>&1 || : \
 %{nil}
 
+%systemd_user_postun() %{nil}
+
 %systemd_postun_with_restart() \
 systemctl daemon-reload >/dev/null 2>&1 || : \
 if [ $1 -ge 1 ] ; then \
@@ -63,6 +74,8 @@
 fi \
 %{nil}
 
+%systemd_user_postun_with_restart() %{nil}
+
 %udev_hwdb_update() \
 udevadm hwdb --update >/dev/null 2>&1 || : \
 %{nil}
diff -urN systemd-216/src/core/main.c systemd-217/src/core/main.c
--- systemd-216/src/core/main.c	2014-11-03 09:35:37.233270323 -0800
+++ systemd-217/src/core/main.c	2014-11-03 09:33:49.294181974 -0800
@@ -116,9 +116,6 @@
 static bool arg_default_cpu_accounting = false;
 static bool arg_default_blockio_accounting = false;
 static bool arg_default_memory_accounting = false;
-static usec_t arg_start_timeout_usec = DEFAULT_MANAGER_START_TIMEOUT_USEC;
-static FailureAction arg_start_timeout_action = FAILURE_ACTION_POWEROFF_FORCE;
-static char *arg_start_timeout_reboot_arg = NULL;
 
 static void nop_handler(int sig) {}
 
@@ -626,6 +623,9 @@
 }
 
 static int parse_config_file(void) {
+        usec_t start_timeout_usec = 0;
+        FailureAction start_timeout_action = FAILURE_ACTION_NONE;
+        char *start_timeout_reboot_arg = NULL;
 
         const ConfigTableItem items[] = {
                 { "Manager", "LogLevel",                  config_parse_level2,           0, NULL                                   },
@@ -673,9 +673,9 @@
                 { "Manager", "DefaultCPUAccounting",      config_parse_bool,             0, &arg_default_cpu_accounting            },
                 { "Manager", "DefaultBlockIOAccounting",  config_parse_bool,             0, &arg_default_blockio_accounting        },
                 { "Manager", "DefaultMemoryAccounting",   config_parse_bool,             0, &arg_default_memory_accounting         },
-                { "Manager", "StartTimeoutSec",           config_parse_sec,              0, &arg_start_timeout_usec                },
-                { "Manager", "StartTimeoutAction",        config_parse_failure_action,   0, &arg_start_timeout_action              },
-                { "Manager", "StartTimeoutRebootArgument",config_parse_string,           0, &arg_start_timeout_reboot_arg          },
+                { "Manager", "StartTimeoutSec",           config_parse_sec,              0, &start_timeout_usec                    },
+                { "Manager", "StartTimeoutAction",        config_parse_failure_action,   0, &start_timeout_action                  },
+                { "Manager", "StartTimeoutRebootArgument",config_parse_string,           0, &start_timeout_reboot_arg              },
                 {}
         };
 
@@ -687,6 +687,10 @@
                      config_item_table_lookup, items,
                      false, false, true, NULL);
 
+        if (start_timeout_usec != 0 || start_timeout_action != FAILURE_ACTION_NONE)
+                log_warning("StartTimeoutSec, StartTimeoutAction, StartTimeoutRebootArgument settings have\n"
+                            "been replaced by JobTimeoutSec, JobTimeoutAction, JobTimeoutReboot, ignoring.");
+
         return 0;
 }
 
@@ -1299,16 +1303,16 @@
                 if (!skip_setup) {
                         mount_setup_early();
                         dual_timestamp_get(&security_start_timestamp);
-                        if (selinux_setup(&loaded_policy) < 0)
+                        if (mac_selinux_setup(&loaded_policy) < 0)
                                 goto finish;
                         if (ima_setup() < 0)
                                 goto finish;
-                        if (smack_setup(&loaded_policy) < 0)
+                        if (mac_smack_setup(&loaded_policy) < 0)
                                 goto finish;
                         dual_timestamp_get(&security_finish_timestamp);
                 }
 
-                if (label_init(NULL) < 0)
+                if (mac_selinux_init(NULL) < 0)
                         goto finish;
 
                 if (!skip_setup) {
@@ -1635,9 +1639,6 @@
         m->default_memory_accounting = arg_default_memory_accounting;
         m->runtime_watchdog = arg_runtime_watchdog;
         m->shutdown_watchdog = arg_shutdown_watchdog;
-        m->start_timeout_usec = arg_start_timeout_usec;
-        m->start_timeout_action = arg_start_timeout_action;
-        free_and_strdup(&m->start_timeout_reboot_arg, arg_start_timeout_reboot_arg);
 
         m->userspace_timestamp = userspace_timestamp;
         m->kernel_timestamp = kernel_timestamp;
@@ -1827,10 +1828,7 @@
         set_free(arg_syscall_archs);
         arg_syscall_archs = NULL;
 
-        free(arg_start_timeout_reboot_arg);
-        arg_start_timeout_reboot_arg = NULL;
-
-        label_finish();
+        mac_selinux_finish();
 
         if (reexecute) {
                 const char **args;
diff -urN systemd-216/src/core/manager.c systemd-217/src/core/manager.c
--- systemd-216/src/core/manager.c	2014-11-03 09:35:37.287270867 -0800
+++ systemd-217/src/core/manager.c	2014-11-03 09:33:49.232181348 -0800
@@ -25,6 +25,8 @@
 #include <signal.h>
 #include <sys/wait.h>
 #include <unistd.h>
+#include <sys/inotify.h>
+#include <sys/epoll.h>
 #include <sys/poll.h>
 #include <sys/reboot.h>
 #include <sys/ioctl.h>
@@ -75,6 +77,7 @@
 #include "dbus-job.h"
 #include "dbus-manager.h"
 #include "bus-kernel.h"
+#include "time-util.h"
 
 /* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */
 #define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC)
@@ -84,8 +87,6 @@
 #define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
 #define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
 
-#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
-
 static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
 static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
 static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
@@ -193,7 +194,7 @@
         if (job_get_timeout(j, &x) > 0)
                 format_timespan(limit, sizeof(limit), x - j->begin_usec, 1*USEC_PER_SEC);
 
-        manager_status_printf(m, true, cylon,
+        manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
                               "%sA %s job is running for %s (%s / %s)",
                               strempty(job_of_n),
                               job_type_to_string(j->type),
@@ -202,6 +203,96 @@
 
 }
 
+static int have_ask_password(void) {
+        _cleanup_closedir_ DIR *dir;
+
+        dir = opendir("/run/systemd/ask-password");
+        if (!dir) {
+                if (errno == ENOENT)
+                        return false;
+                else
+                        return -errno;
+        }
+
+        for (;;) {
+                struct dirent *de;
+
+                errno = 0;
+                de = readdir(dir);
+                if (!de && errno != 0)
+                        return -errno;
+                if (!de)
+                        return false;
+
+                if (startswith(de->d_name, "ask."))
+                        return true;
+        }
+}
+
+static int manager_dispatch_ask_password_fd(sd_event_source *source,
+                                            int fd, uint32_t revents, void *userdata) {
+        Manager *m = userdata;
+
+        assert(m);
+
+        flush_fd(fd);
+
+        m->have_ask_password = have_ask_password();
+        if (m->have_ask_password < 0)
+                /* Log error but continue. Negative have_ask_password
+                 * is treated as unknown status. */
+                log_error("Failed to list /run/systemd/ask-password: %s", strerror(m->have_ask_password));
+
+        return 0;
+}
+
+static void manager_close_ask_password(Manager *m) {
+        assert(m);
+
+        m->ask_password_inotify_fd = safe_close(m->ask_password_inotify_fd);
+        m->ask_password_event_source = sd_event_source_unref(m->ask_password_event_source);
+        m->have_ask_password = -EINVAL;
+}
+
+static int manager_check_ask_password(Manager *m) {
+        int r;
+
+        assert(m);
+
+        if (!m->ask_password_event_source) {
+                assert(m->ask_password_inotify_fd < 0);
+
+                mkdir_p_label("/run/systemd/ask-password", 0755);
+
+                m->ask_password_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
+                if (m->ask_password_inotify_fd < 0) {
+                        log_error("inotify_init1() failed: %m");
+                        return -errno;
+                }
+
+                if (inotify_add_watch(m->ask_password_inotify_fd, "/run/systemd/ask-password", IN_CREATE|IN_DELETE|IN_MOVE) < 0) {
+                        log_error("Failed to add watch on /run/systemd/ask-password: %m");
+                        manager_close_ask_password(m);
+                        return -errno;
+                }
+
+                r = sd_event_add_io(m->event, &m->ask_password_event_source,
+                                    m->ask_password_inotify_fd, EPOLLIN,
+                                    manager_dispatch_ask_password_fd, m);
+                if (r < 0) {
+                        log_error("Failed to add event source for /run/systemd/ask-password: %m");
+                        manager_close_ask_password(m);
+                        return -errno;
+                }
+
+                /* Queries might have been added meanwhile... */
+                manager_dispatch_ask_password_fd(m->ask_password_event_source,
+                                                 m->ask_password_inotify_fd, EPOLLIN, m);
+        }
+
+        return m->have_ask_password;
+}
+
 static int manager_watch_idle_pipe(Manager *m) {
         int r;
 
@@ -308,11 +399,14 @@
         if (m->test_run)
                 return 0;
 
-        /* We are not interested in SIGSTOP and friends. */
         assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
 
-        assert_se(sigemptyset(&mask) == 0);
+        /* We make liberal use of realtime signals here. On
+         * Linux/glibc we have 30 of them (with the exception of Linux
+         * on hppa, see below), between SIGRTMIN+0 ... SIGRTMIN+30
+         * (aka SIGRTMAX). */
 
+        assert_se(sigemptyset(&mask) == 0);
         sigset_add_many(&mask,
                         SIGCHLD,     /* Child died */
                         SIGTERM,     /* Reexecute daemon */
@@ -322,6 +416,7 @@
                         SIGINT,      /* Kernel sends us this on control-alt-del */
                         SIGWINCH,    /* Kernel sends us this on kbrequest (alt-arrowup) */
                         SIGPWR,      /* Some kernel drivers and upsd send us this on power failure */
+
                         SIGRTMIN+0,  /* systemd: start default.target */
                         SIGRTMIN+1,  /* systemd: isolate rescue.target */
                         SIGRTMIN+2,  /* systemd: isolate emergency.target */
@@ -329,19 +424,40 @@
                         SIGRTMIN+4,  /* systemd: start poweroff.target */
                         SIGRTMIN+5,  /* systemd: start reboot.target */
                         SIGRTMIN+6,  /* systemd: start kexec.target */
+
+                        /* ... space for more special targets ... */
+
                         SIGRTMIN+13, /* systemd: Immediate halt */
                         SIGRTMIN+14, /* systemd: Immediate poweroff */
                         SIGRTMIN+15, /* systemd: Immediate reboot */
                         SIGRTMIN+16, /* systemd: Immediate kexec */
+
+                        /* ... space for more immediate system state changes ... */
+
                         SIGRTMIN+20, /* systemd: enable status messages */
                         SIGRTMIN+21, /* systemd: disable status messages */
                         SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
                         SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
                         SIGRTMIN+24, /* systemd: Immediate exit (--user only) */
+
+                        /* .. one free signal here ... */
+
+#if !defined(__hppa64__) && !defined(__hppa__)
+                        /* Apparently Linux on hppa has fewer RT
+                         * signals (SIGRTMAX is SIGRTMIN+25 there),
+                         * hence let's not try to make use of them
+                         * here. Since these commands are accessible
+                         * by different means and only really a safety
+                         * net, the missing functionality on hppa
+                         * shouldn't matter. */
+
                         SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */
                         SIGRTMIN+27, /* systemd: set log target to console */
                         SIGRTMIN+28, /* systemd: set log target to kmsg */
                         SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg (obsolete)*/
+
+                        /* ... one free signal here SIGRTMIN+30 ... */
+#endif
                         -1);
         assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
 
@@ -435,14 +551,15 @@
         m->running_as = running_as;
         m->exit_code = _MANAGER_EXIT_CODE_INVALID;
         m->default_timer_accuracy_usec = USEC_PER_MINUTE;
-        m->start_timeout_usec = DEFAULT_MANAGER_START_TIMEOUT_USEC;
-        m->start_timeout_action = FAILURE_ACTION_POWEROFF_FORCE;
 
         m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;
 
         m->pin_cgroupfs_fd = m->notify_fd = m->signal_fd = m->time_change_fd = m->dev_autofs_fd = m->private_listen_fd = m->kdbus_fd = -1;
         m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
 
+        m->ask_password_inotify_fd = -1;
+        m->have_ask_password = -EINVAL; /* we don't know */
+
         m->test_run = test_run;
 
         r = manager_default_environment(m);
@@ -837,10 +954,9 @@
         safe_close(m->time_change_fd);
         safe_close(m->kdbus_fd);
 
-        manager_close_idle_pipe(m);
+        manager_close_ask_password(m);
 
-        sd_event_source_unref(m->start_timeout_event_source);
-        free(m->start_timeout_reboot_arg);
+        manager_close_idle_pipe(m);
 
         udev_unref(m->udev);
         sd_event_unref(m->event);
@@ -989,20 +1105,6 @@
         return 0;
 }
 
-static int on_start_timeout(sd_event_source *s, usec_t usec, void *userdata) {
-        Manager *m = userdata;
-
-        assert(s);
-        assert(m);
-
-        m->start_timeout_event_source = sd_event_source_unref(m->start_timeout_event_source);
-
-        log_error("Startup timed out.");
-
-        failure_action(m, m->start_timeout_action, m->start_timeout_reboot_arg);
-        return 0;
-}
-
 int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
         int r, q;
 
@@ -1075,22 +1177,6 @@
                 m->send_reloading_done = true;
         }
 
-        /* Possibly set up a start timeout */
-        if (!dual_timestamp_is_set(&m->finish_timestamp)) {
-                m->start_timeout_event_source = sd_event_source_unref(m->start_timeout_event_source);
-
-                if (m->start_timeout_usec) {
-                        r = sd_event_add_time(
-                                        m->event,
-                                        &m->start_timeout_event_source,
-                                        CLOCK_MONOTONIC,
-                                        now(CLOCK_MONOTONIC) + m->start_timeout_usec, 0,
-                                        on_start_timeout, m);
-                        if (r < 0)
-                                log_error("Failed to add start timeout event: %s", strerror(-r));
-                }
-        }
-
         return r;
 }
 
@@ -2498,44 +2584,13 @@
         return unit_inactive_or_pending(u);
 }
 
-void manager_check_finished(Manager *m) {
+static void manager_notify_finished(Manager *m) {
         char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
         usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec;
-        Unit *u = NULL;
-        Iterator i;
 
-        assert(m);
-
-        if (m->n_running_jobs == 0)
-                m->jobs_in_progress_event_source = sd_event_source_unref(m->jobs_in_progress_event_source);
-
-        if (hashmap_size(m->jobs) > 0) {
-
-                if (m->jobs_in_progress_event_source)
-                        sd_event_source_set_time(m->jobs_in_progress_event_source, now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC);
-
-                return;
-        }
-
-        manager_flip_auto_status(m, false);
-
-        /* Notify Type=idle units that we are done now */
-        m->idle_pipe_event_source = sd_event_source_unref(m->idle_pipe_event_source);
-        manager_close_idle_pipe(m);
-
-        /* Turn off confirm spawn now */
-        m->confirm_spawn = false;
-
-        /* This is no longer the first boot */
-        manager_set_first_boot(m, false);
-
-        if (dual_timestamp_is_set(&m->finish_timestamp))
+        if (m->test_run)
                 return;
 
-        dual_timestamp_get(&m->finish_timestamp);
-
-        m->start_timeout_event_source = sd_event_source_unref(m->start_timeout_event_source);
-
         if (m->running_as == SYSTEMD_SYSTEM && detect_container(NULL) <= 0) {
 
                 /* Note that m->kernel_usec.monotonic is always at 0,
@@ -2590,10 +2645,6 @@
                            NULL);
         }
 
-        SET_FOREACH(u, m->startup_units, i)
-                if (u->cgroup_path)
-                        cgroup_context_apply(unit_get_cgroup_context(u), unit_get_cgroup_mask(u), u->cgroup_path, manager_state(m));
-
         bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
 
         sd_notifyf(false,
@@ -2602,6 +2653,50 @@
                    format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC));
 }
 
+void manager_check_finished(Manager *m) {
+        Unit *u = NULL;
+        Iterator i;
+
+        assert(m);
+
+        if (m->n_running_jobs == 0)
+                m->jobs_in_progress_event_source = sd_event_source_unref(m->jobs_in_progress_event_source);
+
+        if (hashmap_size(m->jobs) > 0) {
+
+                if (m->jobs_in_progress_event_source)
+                        sd_event_source_set_time(m->jobs_in_progress_event_source, now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC);
+
+                return;
+        }
+
+        manager_flip_auto_status(m, false);
+
+        /* Notify Type=idle units that we are done now */
+        m->idle_pipe_event_source = sd_event_source_unref(m->idle_pipe_event_source);
+        manager_close_idle_pipe(m);
+
+        /* Turn off confirm spawn now */
+        m->confirm_spawn = false;
+
+        /* No need to update ask password status when we're going non-interactive */
+        manager_close_ask_password(m);
+
+        /* This is no longer the first boot */
+        manager_set_first_boot(m, false);
+
+        if (dual_timestamp_is_set(&m->finish_timestamp))
+                return;
+
+        dual_timestamp_get(&m->finish_timestamp);
+
+        manager_notify_finished(m);
+
+        SET_FOREACH(u, m->startup_units, i)
+                if (u->cgroup_path)
+                        cgroup_context_apply(unit_get_cgroup_context(u), unit_get_cgroup_mask(u), u->cgroup_path, manager_state(m));
+}
+
 static int create_generator_dir(Manager *m, char **generator, const char *name) {
         char *p;
         int r;
@@ -2844,7 +2939,7 @@
                 unlink("/run/systemd/show-status");
 }
 
-static bool manager_get_show_status(Manager *m) {
+static bool manager_get_show_status(Manager *m, StatusType type) {
         assert(m);
 
         if (m->running_as != SYSTEMD_SYSTEM)
@@ -2856,12 +2951,15 @@
         if (!IN_SET(manager_state(m), MANAGER_INITIALIZING, MANAGER_STARTING, MANAGER_STOPPING))
                 return false;
 
+        /* If we cannot find out the status properly, just proceed. */
+        if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0)
+                return false;
+
         if (m->show_status > 0)
                 return true;
 
         /* If Plymouth is running make sure we show the status, so
          * that there's something nice to see when people press Esc */
-
         return plymouth_running();
 }
 
@@ -2879,19 +2977,19 @@
                 unlink("/run/systemd/first-boot");
 }
 
-void manager_status_printf(Manager *m, bool ephemeral, const char *status, const char *format, ...) {
+void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) {
         va_list ap;
 
-        if (!manager_get_show_status(m))
+        if (!manager_get_show_status(m, type))
                 return;
 
         /* XXX We should totally drop the check for ephemeral here
          * and thus effectively make 'Type=idle' pointless. */
-        if (ephemeral && m->n_on_console > 0)
+        if (type == STATUS_TYPE_EPHEMERAL && m->n_on_console > 0)
                 return;
 
         va_start(ap, format);
-        status_vprintf(status, true, ephemeral, format, ap);
+        status_vprintf(status, true, type == STATUS_TYPE_EPHEMERAL, format, ap);
         va_end(ap);
 }
 
diff -urN systemd-216/src/core/manager.h systemd-217/src/core/manager.h
--- systemd-216/src/core/manager.h	2014-11-03 09:35:22.069117423 -0800
+++ systemd-217/src/core/manager.h	2014-10-28 09:25:51.560723266 -0700
@@ -33,8 +33,6 @@
 /* Enforce upper limit how many names we allow */
 #define MANAGER_MAX_NAMES 131072 /* 128K */
 
-#define DEFAULT_MANAGER_START_TIMEOUT_USEC (15*USEC_PER_MINUTE)
-
 typedef struct Manager Manager;
 
 typedef enum ManagerState {
@@ -62,6 +60,12 @@
         _MANAGER_EXIT_CODE_INVALID = -1
 } ManagerExitCode;
 
+typedef enum StatusType {
+        STATUS_TYPE_EPHEMERAL,
+        STATUS_TYPE_NORMAL,
+        STATUS_TYPE_EMERGENCY,
+} StatusType;
+
 #include "unit.h"
 #include "job.h"
 #include "hashmap.h"
@@ -267,6 +271,11 @@
         unsigned n_on_console;
         unsigned jobs_in_progress_iteration;
 
+        /* Do we have any outstanding password prompts? */
+        int have_ask_password;
+        int ask_password_inotify_fd;
+        sd_event_source *ask_password_event_source;
+
         /* Type=idle pipes */
         int idle_pipe[4];
         sd_event_source *idle_pipe_event_source;
@@ -284,12 +293,6 @@
 
         /* Used for processing polkit authorization responses */
         Hashmap *polkit_registry;
-
-        /* System wide startup timeouts */
-        usec_t start_timeout_usec;
-        sd_event_source *start_timeout_event_source;
-        FailureAction start_timeout_action;
-        char *start_timeout_reboot_arg;
 };
 
 int manager_new(SystemdRunningAs running_as, bool test_run, Manager **m);
@@ -352,7 +355,7 @@
 void manager_set_show_status(Manager *m, ShowStatus mode);
 void manager_set_first_boot(Manager *m, bool b);
 
-void manager_status_printf(Manager *m, bool ephemeral, const char *status, const char *format, ...) _printf_(4,5);
+void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5);
 void manager_flip_auto_status(Manager *m, bool enable);
 
 Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path);
diff -urN systemd-216/src/core/mount-setup.c systemd-217/src/core/mount-setup.c
--- systemd-216/src/core/mount-setup.c	2014-11-03 09:35:37.208270071 -0800
+++ systemd-217/src/core/mount-setup.c	2014-10-23 08:20:23.344118433 -0700
@@ -82,9 +82,9 @@
           NULL,       MNT_NONE },
 #ifdef HAVE_SMACK
         { "smackfs",    "/sys/fs/smackfs",           "smackfs",    "smackfsdef=*", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME,
-          use_smack,  MNT_FATAL },
+          mac_smack_use, MNT_FATAL },
         { "tmpfs",      "/dev/shm",                  "tmpfs",      "mode=1777,smackfsroot=*", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
-          use_smack,  MNT_FATAL },
+          mac_smack_use, MNT_FATAL },
 #endif
         { "tmpfs",      "/dev/shm",                  "tmpfs",      "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
           NULL,       MNT_FATAL|MNT_IN_CONTAINER },
@@ -92,7 +92,7 @@
           NULL,       MNT_IN_CONTAINER },
 #ifdef HAVE_SMACK
         { "tmpfs",      "/run",                      "tmpfs",      "mode=755,smackfsroot=*", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
-          use_smack,  MNT_FATAL },
+          mac_smack_use, MNT_FATAL },
 #endif
         { "tmpfs",      "/run",                      "tmpfs",      "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
           NULL,       MNT_FATAL|MNT_IN_CONTAINER },
diff -urN systemd-216/src/core/namespace.c systemd-217/src/core/namespace.c
--- systemd-216/src/core/namespace.c	2014-11-03 09:35:34.854246335 -0800
+++ systemd-217/src/core/namespace.c	2014-10-23 12:36:56.809756234 -0700
@@ -225,9 +225,9 @@
                         goto fail;
                 }
 
-                label_context_set(d, st.st_mode);
+                mac_selinux_create_file_prepare(d, st.st_mode);
                 r = mknod(dn, st.st_mode, st.st_rdev);
-                label_context_clear();
+                mac_selinux_create_file_clear();
 
                 if (r < 0) {
                         r = -errno;
@@ -424,9 +424,9 @@
                 char** read_write_dirs,
                 char** read_only_dirs,
                 char** inaccessible_dirs,
-                char* tmp_dir,
-                char* var_tmp_dir,
-                char* bus_endpoint_path,
+                const char* tmp_dir,
+                const char* var_tmp_dir,
+                const char* bus_endpoint_path,
                 bool private_dev,
                 ProtectHome protect_home,
                 ProtectSystem protect_system,
diff -urN systemd-216/src/core/namespace.h systemd-217/src/core/namespace.h
--- systemd-216/src/core/namespace.h	2014-11-03 09:35:26.026157322 -0800
+++ systemd-217/src/core/namespace.h	2014-10-17 04:49:08.145601576 -0700
@@ -44,9 +44,9 @@
 int setup_namespace(char **read_write_dirs,
                     char **read_only_dirs,
                     char **inaccessible_dirs,
-                    char *tmp_dir,
-                    char *var_tmp_dir,
-                    char *endpoint_path,
+                    const char *tmp_dir,
+                    const char *var_tmp_dir,
+                    const char *endpoint_path,
                     bool private_dev,
                     ProtectHome protect_home,
                     ProtectSystem protect_system,
diff -urN systemd-216/src/core/org.freedesktop.systemd1.policy.in.in systemd-217/src/core/org.freedesktop.systemd1.policy.in.in
--- systemd-216/src/core/org.freedesktop.systemd1.policy.in.in	2014-08-18 09:11:26.885137008 -0700
+++ systemd-217/src/core/org.freedesktop.systemd1.policy.in.in	2014-10-13 08:19:31.290674685 -0700
@@ -27,17 +27,6 @@
                 <annotate key="org.freedesktop.policykit.exec.path">@rootlibexecdir@/systemd-reply-password</annotate>
         </action>
 
-        <action id="org.freedesktop.systemd1.bus-access">
-                <_description>Privileged system and service manager access</_description>
-                <_message>Authentication is required to access the system and service manager.</_message>
-                <defaults>
-                        <allow_any>no</allow_any>
-                        <allow_inactive>no</allow_inactive>
-                        <allow_active>auth_admin_keep</allow_active>
-                </defaults>
-                <annotate key="org.freedesktop.policykit.exec.path">@bindir@/systemd-stdio-bridge</annotate>
-        </action>
-
         <action id="org.freedesktop.systemd1.manage-units">
                 <_description>Manage system services or units</_description>
                 <_message>Authentication is required to manage system services or units.</_message>
diff -urN systemd-216/src/core/selinux-access.c systemd-217/src/core/selinux-access.c
--- systemd-216/src/core/selinux-access.c	2014-11-03 09:35:36.031258203 -0800
+++ systemd-217/src/core/selinux-access.c	2014-10-28 06:31:48.703077417 -0700
@@ -53,7 +53,7 @@
 
 /*
    Any time an access gets denied this callback will be called
-   with the aduit data.  We then need to just copy the audit data into the msgbuf.
+   with the audit data.  We then need to just copy the audit data into the msgbuf.
 */
 static int audit_callback(
                 void *auditdata,
@@ -64,14 +64,20 @@
         const struct audit_info *audit = auditdata;
         uid_t uid = 0, login_uid = 0;
         gid_t gid = 0;
-
-        sd_bus_creds_get_audit_login_uid(audit->creds, &login_uid);
-        sd_bus_creds_get_uid(audit->creds, &uid);
-        sd_bus_creds_get_gid(audit->creds, &gid);
+        char login_uid_buf[DECIMAL_STR_MAX(uid_t)] = "n/a";
+        char uid_buf[DECIMAL_STR_MAX(uid_t)] = "n/a";
+        char gid_buf[DECIMAL_STR_MAX(gid_t)] = "n/a";
+
+        if (sd_bus_creds_get_audit_login_uid(audit->creds, &login_uid) >= 0)
+                snprintf(login_uid_buf, sizeof(login_uid_buf), UID_FMT, login_uid);
+        if (sd_bus_creds_get_uid(audit->creds, &uid) >= 0)
+                snprintf(uid_buf, sizeof(uid_buf), UID_FMT, uid);
+        if (sd_bus_creds_get_gid(audit->creds, &gid) >= 0)
+                snprintf(gid_buf, sizeof(gid_buf), GID_FMT, gid);
 
         snprintf(msgbuf, msgbufsize,
-                 "auid=%d uid=%d gid=%d%s%s%s%s%s%s",
-                 login_uid, uid, gid,
+                 "auid=%s uid=%s gid=%s%s%s%s%s%s%s",
+                 login_uid_buf, uid_buf, gid_buf,
                  audit->path ? " path=\"" : "", strempty(audit->path), audit->path ? "\"" : "",
                  audit->cmdline ? " cmdline=\"" : "", strempty(audit->cmdline), audit->cmdline ? "\"" : "");
 
@@ -136,13 +142,13 @@
         return r;
 }
 
-static int selinux_access_init(sd_bus_error *error) {
+static int mac_selinux_access_init(sd_bus_error *error) {
         int r;
 
         if (initialized)
                 return 0;
 
-        if (!use_selinux())
+        if (!mac_selinux_use())
                 return 0;
 
         r = access_init();
@@ -152,14 +158,17 @@
         initialized = true;
         return 0;
 }
+#endif
 
-void selinux_access_free(void) {
+void mac_selinux_access_free(void) {
 
+#ifdef HAVE_SELINUX
         if (!initialized)
                 return;
 
         avc_destroy();
         initialized = false;
+#endif
 }
 
 /*
@@ -168,12 +177,13 @@
    If the machine is in permissive mode it will return ok.  Audit messages will
    still be generated if the access would be denied in enforcing mode.
 */
-int selinux_generic_access_check(
+int mac_selinux_generic_access_check(
                 sd_bus_message *message,
                 const char *path,
                 const char *permission,
                 sd_bus_error *error) {
 
+#ifdef HAVE_SELINUX
         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
         const char *tclass = NULL, *scon = NULL;
         struct audit_info audit_info = {};
@@ -186,10 +196,10 @@
         assert(permission);
         assert(error);
 
-        if (!use_selinux())
+        if (!mac_selinux_use())
                 return 0;
 
-        r = selinux_access_init(error);
+        r = mac_selinux_access_init(error);
         if (r < 0)
                 return r;
 
@@ -248,13 +258,17 @@
         }
 
         return r;
+#else
+        return 0;
+#endif
 }
 
-int selinux_unit_access_check_strv(char **units,
+int mac_selinux_unit_access_check_strv(char **units,
                                 sd_bus_message *message,
                                 Manager *m,
                                 const char *permission,
                                 sd_bus_error *error) {
+#ifdef HAVE_SELINUX
         char **i;
         Unit *u;
         int r;
@@ -262,35 +276,11 @@
         STRV_FOREACH(i, units) {
                 u = manager_get_unit(m, *i);
                 if (u) {
-                        r = selinux_unit_access_check(u, message, permission, error);
+                        r = mac_selinux_unit_access_check(u, message, permission, error);
                         if (r < 0)
                                 return r;
                 }
         }
-
-        return 0;
-}
-
-#else
-
-int selinux_generic_access_check(
-                sd_bus_message *message,
-                const char *path,
-                const char *permission,
-                sd_bus_error *error) {
-
-        return 0;
-}
-
-void selinux_access_free(void) {
-}
-
-int selinux_unit_access_check_strv(char **units,
-                                sd_bus_message *message,
-                                Manager *m,
-                                const char *permission,
-                                sd_bus_error *error) {
+#endif
         return 0;
 }
-
-#endif
diff -urN systemd-216/src/core/selinux-access.h systemd-217/src/core/selinux-access.h
--- systemd-216/src/core/selinux-access.h	2014-11-03 09:35:36.032258213 -0800
+++ systemd-217/src/core/selinux-access.h	2014-10-28 06:31:48.704077415 -0700
@@ -26,26 +26,26 @@
 #include "bus-util.h"
 #include "manager.h"
 
-void selinux_access_free(void);
+void mac_selinux_access_free(void);
 
-int selinux_generic_access_check(sd_bus_message *message, const char *path, const char *permission, sd_bus_error *error);
+int mac_selinux_generic_access_check(sd_bus_message *message, const char *path, const char *permission, sd_bus_error *error);
 
-int selinux_unit_access_check_strv(char **units, sd_bus_message *message, Manager *m, const char *permission, sd_bus_error *error);
+int mac_selinux_unit_access_check_strv(char **units, sd_bus_message *message, Manager *m, const char *permission, sd_bus_error *error);
 
 #ifdef HAVE_SELINUX
 
-#define selinux_access_check(message, permission, error) \
-        selinux_generic_access_check((message), NULL, (permission), (error))
+#define mac_selinux_access_check(message, permission, error) \
+        mac_selinux_generic_access_check((message), NULL, (permission), (error))
 
-#define selinux_unit_access_check(unit, message, permission, error) \
+#define mac_selinux_unit_access_check(unit, message, permission, error) \
         ({                                                              \
                 Unit *_unit = (unit);                                   \
-                selinux_generic_access_check((message), _unit->fragment_path ?: _unit->fragment_path, (permission), (error)); \
+                mac_selinux_generic_access_check((message), _unit->fragment_path ?: _unit->fragment_path, (permission), (error)); \
         })
 
 #else
 
-#define selinux_access_check(message, permission, error) 0
-#define selinux_unit_access_check(unit, message, permission, error) 0
+#define mac_selinux_access_check(message, permission, error) 0
+#define mac_selinux_unit_access_check(unit, message, permission, error) 0
 
 #endif
diff -urN systemd-216/src/core/selinux-setup.c systemd-217/src/core/selinux-setup.c
--- systemd-216/src/core/selinux-setup.c	2014-05-16 11:04:01.463524901 -0700
+++ systemd-217/src/core/selinux-setup.c	2014-10-28 06:31:48.704077415 -0700
@@ -43,7 +43,7 @@
 }
 #endif
 
-int selinux_setup(bool *loaded_policy) {
+int mac_selinux_setup(bool *loaded_policy) {
 
 #ifdef HAVE_SELINUX
         int enforce = 0;
@@ -84,10 +84,10 @@
                 char timespan[FORMAT_TIMESPAN_MAX];
                 char *label;
 
-                retest_selinux();
+                mac_selinux_retest();
 
                 /* Transition to the new context */
-                r = label_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label);
+                r = mac_selinux_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label);
                 if (r < 0 || label == NULL) {
                         log_open();
                         log_error("Failed to compute init label, ignoring.");
@@ -98,7 +98,7 @@
                         if (r < 0)
                                 log_error("Failed to transition into init label '%s', ignoring.", label);
 
-                        label_free(label);
+                        mac_selinux_free(label);
                 }
 
                 after_load = now(CLOCK_MONOTONIC);
diff -urN systemd-216/src/core/selinux-setup.h systemd-217/src/core/selinux-setup.h
--- systemd-216/src/core/selinux-setup.h	2014-02-12 18:42:32.016692299 -0800
+++ systemd-217/src/core/selinux-setup.h	2014-10-28 06:31:48.704077415 -0700
@@ -23,4 +23,4 @@
 
 #include <stdbool.h>
 
-int selinux_setup(bool *loaded_policy);
+int mac_selinux_setup(bool *loaded_policy);
diff -urN systemd-216/src/core/service.c systemd-217/src/core/service.c
--- systemd-216/src/core/service.c	2014-11-03 09:35:36.667264616 -0800
+++ systemd-217/src/core/service.c	2014-11-03 09:33:48.500173968 -0800
@@ -883,7 +883,6 @@
                 bool apply_permissions,
                 bool apply_chroot,
                 bool apply_tty_stdin,
-                bool set_notify_socket,
                 bool is_control,
                 pid_t *_pid) {
 
@@ -948,7 +947,7 @@
                 goto fail;
         }
 
-        if (set_notify_socket)
+        if (is_control ? s->notify_access == NOTIFY_ALL : s->notify_access != NOTIFY_NONE)
                 if (asprintf(our_env + n_env++, "NOTIFY_SOCKET=%s", UNIT(s)->manager->notify_socket) < 0) {
                         r = -ENOMEM;
                         goto fail;
@@ -1153,7 +1152,6 @@
                                   !s->permissions_start_only,
                                   !s->root_directory_start_only,
                                   true,
-                                  false,
                                   true,
                                   &s->control_pid);
                 if (r < 0)
@@ -1253,7 +1251,6 @@
                                   !s->permissions_start_only,
                                   !s->root_directory_start_only,
                                   false,
-                                  false,
                                   true,
                                   &s->control_pid);
                 if (r < 0)
@@ -1316,7 +1313,6 @@
                                   !s->permissions_start_only,
                                   !s->root_directory_start_only,
                                   false,
-                                  false,
                                   true,
                                   &s->control_pid);
                 if (r < 0)
@@ -1383,7 +1379,6 @@
                           true,
                           true,
                           true,
-                          s->notify_access != NOTIFY_NONE,
                           false,
                           &pid);
         if (r < 0)
@@ -1449,7 +1444,6 @@
                                   !s->permissions_start_only,
                                   !s->root_directory_start_only,
                                   true,
-                                  false,
                                   true,
                                   &s->control_pid);
                 if (r < 0)
@@ -1530,7 +1524,6 @@
                                   !s->permissions_start_only,
                                   !s->root_directory_start_only,
                                   false,
-                                  false,
                                   true,
                                   &s->control_pid);
                 if (r < 0)
@@ -1568,7 +1561,6 @@
                           !s->root_directory_start_only,
                           s->control_command_id == SERVICE_EXEC_START_PRE ||
                           s->control_command_id == SERVICE_EXEC_STOP_POST,
-                          false,
                           true,
                           &s->control_pid);
         if (r < 0)
@@ -1611,7 +1603,6 @@
                           true,
                           true,
                           true,
-                          s->notify_access != NOTIFY_NONE,
                           false,
                           &pid);
         if (r < 0)
@@ -2738,7 +2729,7 @@
 
                 /* Try to acquire PID from bus service */
 
-                r = sd_bus_get_owner(u->manager->api_bus, name, SD_BUS_CREDS_PID, &creds);
+                r = sd_bus_get_name_creds(u->manager->api_bus, name, SD_BUS_CREDS_PID, &creds);
                 if (r >= 0)
                         r = sd_bus_creds_get_pid(creds, &pid);
                 if (r >= 0) {
diff -urN systemd-216/src/core/shutdown.c systemd-217/src/core/shutdown.c
--- systemd-216/src/core/shutdown.c	2014-11-03 09:35:23.664133505 -0800
+++ systemd-217/src/core/shutdown.c	2014-10-27 04:48:29.291966279 -0700
@@ -207,7 +207,7 @@
 
         in_container = detect_container(NULL) > 0;
 
-        need_umount = true;
+        need_umount = !in_container;
         need_swapoff = !in_container;
         need_loop_detach = !in_container;
         need_dm_detach = !in_container;
@@ -313,7 +313,7 @@
             access("/run/initramfs/shutdown", X_OK) == 0) {
                 r = switch_root_initramfs();
                 if (r >= 0) {
-                        arguments[0] = (char*) "/shutdown";
+                        argv[0] = (char*) "/shutdown";
 
                         setsid();
                         make_console_stdio();
@@ -321,7 +321,7 @@
                         log_info("Successfully changed into root pivot.\n"
                                  "Returning to initrd...");
 
-                        execv("/shutdown", arguments);
+                        execv("/shutdown", argv);
                         log_error("Failed to execute shutdown binary: %m");
                 } else
                         log_error("Failed to switch root to \"/run/initramfs\": %s", strerror(-r));
diff -urN systemd-216/src/core/smack-setup.c systemd-217/src/core/smack-setup.c
--- systemd-216/src/core/smack-setup.c	2014-11-03 09:35:27.585173041 -0800
+++ systemd-217/src/core/smack-setup.c	2014-10-28 06:31:48.704077415 -0700
@@ -116,7 +116,7 @@
 
 #endif
 
-int smack_setup(bool *loaded_policy) {
+int mac_smack_setup(bool *loaded_policy) {
 
 #ifdef HAVE_SMACK
 
diff -urN systemd-216/src/core/smack-setup.h systemd-217/src/core/smack-setup.h
--- systemd-216/src/core/smack-setup.h	2014-02-24 08:36:13.742568903 -0800
+++ systemd-217/src/core/smack-setup.h	2014-10-28 06:31:48.705077413 -0700
@@ -23,4 +23,4 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-int smack_setup(bool *loaded_policy);
+int mac_smack_setup(bool *loaded_policy);
diff -urN systemd-216/src/core/snapshot.c systemd-217/src/core/snapshot.c
--- systemd-216/src/core/snapshot.c	2014-06-23 03:40:38.722584818 -0700
+++ systemd-217/src/core/snapshot.c	2014-11-03 09:33:48.849177487 -0800
@@ -208,7 +208,7 @@
                         return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s lacks snapshot suffix.", name);
 
                 if (manager_get_unit(m, name))
-                        sd_bus_error_setf(e, BUS_ERROR_UNIT_EXISTS, "Snapshot %s exists already.", name);
+                        return sd_bus_error_setf(e, BUS_ERROR_UNIT_EXISTS, "Snapshot %s exists already.", name);
 
         } else {
 
diff -urN systemd-216/src/core/socket.c systemd-217/src/core/socket.c
--- systemd-216/src/core/socket.c	2014-11-03 09:35:30.007197462 -0800
+++ systemd-217/src/core/socket.c	2014-11-03 09:33:48.501173978 -0800
@@ -807,6 +807,8 @@
 }
 
 static void socket_apply_socket_options(Socket *s, int fd) {
+        int r;
+
         assert(s);
         assert(fd >= 0);
 
@@ -894,7 +896,7 @@
                         log_warning_unit(UNIT(s)->id, "IP_TOS failed: %m");
 
         if (s->ip_ttl >= 0) {
-                int r, x;
+                int x;
 
                 r = setsockopt(fd, IPPROTO_IP, IP_TTL, &s->ip_ttl, sizeof(s->ip_ttl));
 
@@ -920,27 +922,34 @@
                         log_warning_unit(UNIT(s)->id, "SO_REUSEPORT failed: %m");
         }
 
-        if (s->smack_ip_in)
-                if (smack_label_ip_in_fd(fd, s->smack_ip_in) < 0)
-                        log_error_unit(UNIT(s)->id, "smack_label_ip_in_fd: %m");
-
-        if (s->smack_ip_out)
-                if (smack_label_ip_out_fd(fd, s->smack_ip_out) < 0)
-                        log_error_unit(UNIT(s)->id, "smack_label_ip_out_fd: %m");
+        if (s->smack_ip_in) {
+                r = mac_smack_apply_ip_in_fd(fd, s->smack_ip_in);
+                if (r < 0)
+                        log_error_unit(UNIT(s)->id, "mac_smack_apply_ip_in_fd: %s", strerror(-r));
+        }
+
+        if (s->smack_ip_out) {
+                r = mac_smack_apply_ip_out_fd(fd, s->smack_ip_out);
+                if (r < 0)
+                        log_error_unit(UNIT(s)->id, "mac_smack_apply_ip_out_fd: %s", strerror(-r));
+        }
 }
 
 static void socket_apply_fifo_options(Socket *s, int fd) {
+        int r;
+
         assert(s);
         assert(fd >= 0);
 
         if (s->pipe_size > 0)
                 if (fcntl(fd, F_SETPIPE_SZ, s->pipe_size) < 0)
-                        log_warning_unit(UNIT(s)->id,
-                                         "F_SETPIPE_SZ: %m");
+                        log_warning_unit(UNIT(s)->id, "F_SETPIPE_SZ: %m");
 
-        if (s->smack)
-                if (smack_label_fd(fd, s->smack) < 0)
-                        log_error_unit(UNIT(s)->id, "smack_label_fd: %m");
+        if (s->smack) {
+                r = mac_smack_apply_fd(fd, s->smack);
+                if (r < 0)
+                        log_error_unit(UNIT(s)->id, "mac_smack_apply_fd: %s", strerror(-r));
+        }
 }
 
 static int fifo_address_create(
@@ -958,7 +967,7 @@
 
         mkdir_parents_label(path, directory_mode);
 
-        r = label_context_set(path, S_IFIFO);
+        r = mac_selinux_create_file_prepare(path, S_IFIFO);
         if (r < 0)
                 goto fail;
 
@@ -981,7 +990,7 @@
                 goto fail;
         }
 
-        label_context_clear();
+        mac_selinux_create_file_clear();
 
         if (fstat(fd, &st) < 0) {
                 r = -errno;
@@ -1001,7 +1010,7 @@
         return 0;
 
 fail:
-        label_context_clear();
+        mac_selinux_create_file_clear();
         safe_close(fd);
 
         return r;
@@ -1111,7 +1120,7 @@
                 return 0;
 
         STRV_FOREACH(i, s->symlinks)
-                symlink(p, *i);
+                symlink_label(p, *i);
 
         return 0;
 }
@@ -1130,22 +1139,33 @@
                         continue;
 
                 if (p->type == SOCKET_SOCKET) {
-                        if (!know_label && s->selinux_context_from_net) {
-                                r = label_get_our_label(&label);
-                                if (r < 0)
-                                        return r;
-                                know_label = true;
-                        } else if (!know_label) {
 
-                                r = socket_instantiate_service(s);
-                                if (r < 0)
-                                        return r;
-
-                                if (UNIT_ISSET(s->service) &&
-                                    SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
-                                        r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
-                                        if (r < 0 && r != -EPERM)
-                                                return r;
+                        if (!know_label) {
+                                /* Figure out label, if we don't it know
+                                 * yet. We do it once, for the first
+                                 * socket where we need this and
+                                 * remember it for the rest. */
+
+                                if (s->selinux_context_from_net) {
+                                        /* Get it from the network label */
+
+                                        r = mac_selinux_get_our_label(&label);
+                                        if (r < 0 && r != -EOPNOTSUPP)
+                                                goto rollback;
+
+                                } else {
+                                        /* Get it from the executable we are about to start */
+
+                                        r = socket_instantiate_service(s);
+                                        if (r < 0)
+                                                goto rollback;
+
+                                        if (UNIT_ISSET(s->service) &&
+                                            SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
+                                                r = mac_selinux_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
+                                                if (r < 0 && r != -EPERM && r != -EOPNOTSUPP)
+                                                        goto rollback;
+                                        }
                                 }
 
                                 know_label = true;
@@ -1204,12 +1224,13 @@
                         assert_not_reached("Unknown port type");
         }
 
-        label_free(label);
+        mac_selinux_free(label);
         return 0;
 
 rollback:
         socket_close_fds(s);
-        label_free(label);
+        mac_selinux_free(label);
+
         return r;
 }
 
diff -urN systemd-216/src/core/swap.c systemd-217/src/core/swap.c
--- systemd-216/src/core/swap.c	2014-11-03 09:35:33.152229174 -0800
+++ systemd-217/src/core/swap.c	2014-11-03 09:33:48.502173988 -0800
@@ -152,8 +152,8 @@
         free(s->parameters_fragment.what);
         s->parameters_fragment.what = NULL;
 
-        free(s->parameters_fragment.discard);
-        s->parameters_fragment.discard = NULL;
+        free(s->parameters_fragment.options);
+        s->parameters_fragment.options = NULL;
 
         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
         exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
@@ -191,20 +191,16 @@
 }
 
 static int swap_add_device_links(Swap *s) {
-        SwapParameters *p;
-
         assert(s);
 
         if (!s->what)
                 return 0;
 
-        if (s->from_fragment)
-                p = &s->parameters_fragment;
-        else
+        if (!s->from_fragment)
                 return 0;
 
         if (is_device_path(s->what))
-                return unit_add_node_link(UNIT(s), s->what, !p->noauto && UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
+                return unit_add_node_link(UNIT(s), s->what, UNIT(s)->manager->running_as == SYSTEMD_SYSTEM);
         else
                 /* File based swap devices need to be ordered after
                  * systemd-remount-fs.service, since they might need a
@@ -213,7 +209,6 @@
 }
 
 static int swap_add_default_dependencies(Swap *s) {
-        bool nofail, noauto;
         int r;
 
         assert(s);
@@ -236,17 +231,7 @@
                  * manually, and should not become a dependency of swap.target. */
                 return 0;
 
-        nofail = s->parameters_fragment.nofail;
-        noauto = s->parameters_fragment.noauto;
-
-        if (!noauto) {
-                if (nofail)
-                        r = unit_add_dependency_by_name_inverse(UNIT(s), UNIT_WANTS, SPECIAL_SWAP_TARGET, NULL, true);
-                else
-                        r = unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
-        }
-
-        return r < 0 ? r : 0;
+        return unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
 }
 
 static int swap_verify(Swap *s) {
@@ -371,8 +356,6 @@
                 const char *what,
                 const char *what_proc_swaps,
                 int priority,
-                bool noauto,
-                bool nofail,
                 bool set_flags) {
 
         _cleanup_free_ char *e = NULL;
@@ -435,8 +418,6 @@
         SWAP(u)->from_proc_swaps = true;
 
         p->priority = priority;
-        p->noauto = noauto;
-        p->nofail = nofail;
 
         unit_add_to_dbus_queue(u);
 
@@ -460,7 +441,7 @@
 
         assert(m);
 
-        r = swap_add_one(m, device, device, prio, false, false, set_flags);
+        r = swap_add_one(m, device, device, prio, set_flags);
         if (r < 0)
                 return r;
 
@@ -476,7 +457,7 @@
         /* Add the main device node */
         dn = udev_device_get_devnode(d);
         if (dn && !streq(dn, device))
-                swap_add_one(m, dn, device, prio, false, false, set_flags);
+                swap_add_one(m, dn, device, prio, set_flags);
 
         /* Add additional units for all symlinks */
         first = udev_device_get_devlinks_list_entry(d);
@@ -497,7 +478,7 @@
                             st.st_rdev != udev_device_get_devnum(d))
                                 continue;
 
-                swap_add_one(m, p, device, prio, false, false, set_flags);
+                swap_add_one(m, p, device, prio, set_flags);
         }
 
         return r;
@@ -606,13 +587,9 @@
         if (p)
                 fprintf(f,
                         "%sPriority: %i\n"
-                        "%sNoAuto: %s\n"
-                        "%sNoFail: %s\n"
-                        "%sDiscard: %s\n",
+                        "%sOptions: %s\n",
                         prefix, p->priority,
-                        prefix, yes_no(p->noauto),
-                        prefix, yes_no(p->nofail),
-                        prefix, p->discard ?: "none");
+                        prefix, strempty(p->options));
 
         if (s->control_pid > 0)
                 fprintf(f,
@@ -739,9 +716,74 @@
         swap_enter_dead(s, SWAP_FAILURE_RESOURCES);
 }
 
+static int mount_find_pri(const char *options, int *ret) {
+        const char *opt;
+        char *end;
+        unsigned long r;
+
+        assert(ret);
+
+        if (!options)
+                return 0;
+
+        opt = mount_test_option(options, "pri");
+        if (!opt)
+                return 0;
+
+        opt += strlen("pri");
+        if (*opt != '=')
+                return -EINVAL;
+
+        errno = 0;
+        r = strtoul(opt + 1, &end, 10);
+        if (errno > 0)
+                return -errno;
+
+        if (end == opt + 1 || (*end != ',' && *end != 0))
+                return -EINVAL;
+
+        *ret = (int) r;
+        return 1;
+}
+
+static int mount_find_discard(const char *options, char **ret) {
+        const char *opt;
+        char *ans;
+        size_t len;
+
+        assert(ret);
+
+        if (!options)
+                return 0;
+
+        opt = mount_test_option(options, "discard");
+        if (!opt)
+                return 0;
+
+        opt += strlen("discard");
+        if (*opt == ',' || *opt == '\0')
+                ans = strdup("all");
+        else {
+                if (*opt != '=')
+                        return -EINVAL;
+
+                len = strcspn(opt + 1, ",");
+                if (len == 0)
+                        return -EINVAL;
+
+                ans = strndup(opt + 1, len);
+        }
+
+        if (!ans)
+                return -ENOMEM;
+
+        *ret = ans;
+        return 1;
+}
+
 static void swap_enter_activating(Swap *s) {
-        int r, priority;
-        char *discard;
+        _cleanup_free_ char *discard = NULL;
+        int r, priority = -1;
 
         assert(s);
 
@@ -749,11 +791,11 @@
         s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
 
         if (s->from_fragment) {
+                mount_find_discard(s->parameters_fragment.options, &discard);
+
                 priority = s->parameters_fragment.priority;
-                discard = s->parameters_fragment.discard;
-        } else {
-                priority = -1;
-                discard = NULL;
+                if (priority < 0)
+                        mount_find_pri(s->parameters_fragment.options, &priority);
         }
 
         r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
@@ -770,9 +812,11 @@
         }
 
         if (discard && !streq(discard, "none")) {
-                const char *discard_arg = "--discard";
+                const char *discard_arg;
 
-                if (!streq(discard, "all"))
+                if (streq(discard, "all"))
+                        discard_arg = "--discard";
+                else
                         discard_arg = strappenda("--discard=", discard);
 
                 r = exec_command_append(s->control_command, discard_arg, NULL);
diff -urN systemd-216/src/core/swap.h systemd-217/src/core/swap.h
--- systemd-216/src/core/swap.h	2014-11-03 09:35:32.545223053 -0800
+++ systemd-217/src/core/swap.h	2014-10-28 09:25:51.561723254 -0700
@@ -63,10 +63,8 @@
 
 typedef struct SwapParameters {
         char *what;
-        char *discard;
+        char *options;
         int priority;
-        bool noauto:1;
-        bool nofail:1;
 } SwapParameters;
 
 struct Swap {
diff -urN systemd-216/src/core/system.conf systemd-217/src/core/system.conf
--- systemd-216/src/core/system.conf	2014-11-03 09:35:22.040117130 -0800
+++ systemd-217/src/core/system.conf	2014-10-27 17:38:52.177487956 -0700
@@ -23,9 +23,6 @@
 #CapabilityBoundingSet=
 #SystemCallArchitectures=
 #TimerSlackNSec=
-#StartTimeoutSec=15min
-#StartTimeoutAction=poweroff-force
-#StartTimeoutRebootArgument=
 #DefaultTimerAccuracySec=1min
 #DefaultStandardOutput=journal
 #DefaultStandardError=inherit
diff -urN systemd-216/src/core/transaction.c systemd-217/src/core/transaction.c
--- systemd-216/src/core/transaction.c	2014-11-03 09:35:27.855175764 -0800
+++ systemd-217/src/core/transaction.c	2014-11-03 09:33:49.212181147 -0800
@@ -377,9 +377,9 @@
                 for (k = from; k; k = ((k->generation == generation && k->marker != k) ? k->marker : NULL)) {
 
                         /* logging for j not k here here to provide consistent narrative */
-                        log_info_unit(j->unit->id,
-                                      "Found dependency on %s/%s",
-                                      k->unit->id, job_type_to_string(k->type));
+                        log_warning_unit(j->unit->id,
+                                         "Found dependency on %s/%s",
+                                         k->unit->id, job_type_to_string(k->type));
 
                         if (!delete && hashmap_get(tr->jobs, k->unit) &&
                             !unit_matters_to_anchor(k->unit, k)) {
diff -urN systemd-216/src/core/unit.c systemd-217/src/core/unit.c
--- systemd-216/src/core/unit.c	2014-11-03 09:35:35.991257800 -0800
+++ systemd-217/src/core/unit.c	2014-11-03 09:33:48.503173998 -0800
@@ -520,6 +520,8 @@
         strv_free(u->dropin_paths);
         free(u->instance);
 
+        free(u->job_timeout_reboot_arg);
+
         set_free_free(u->names);
 
         unit_unwatch_all_pids(u);
@@ -553,29 +555,38 @@
         return UNIT_VTABLE(u)->sub_state_to_string(u);
 }
 
-static void complete_move(Set **s, Set **other) {
+static int complete_move(Set **s, Set **other) {
+        int r;
+
         assert(s);
         assert(other);
 
         if (!*other)
-                return;
+                return 0;
 
-        if (*s)
-                set_move(*s, *other);
-        else {
+        if (*s) {
+                r = set_move(*s, *other);
+                if (r < 0)
+                        return r;
+        } else {
                 *s = *other;
                 *other = NULL;
         }
+
+        return 0;
 }
 
-static void merge_names(Unit *u, Unit *other) {
+static int merge_names(Unit *u, Unit *other) {
         char *t;
         Iterator i;
+        int r;
 
         assert(u);
         assert(other);
 
-        complete_move(&u->names, &other->names);
+        r = complete_move(&u->names, &other->names);
+        if (r < 0)
+                return r;
 
         set_free_free(other->names);
         other->names = NULL;
@@ -583,6 +594,29 @@
 
         SET_FOREACH(t, u->names, i)
                 assert_se(hashmap_replace(u->manager->units, t, u) == 0);
+
+        return 0;
+}
+
+static int reserve_dependencies(Unit *u, Unit *other, UnitDependency d) {
+        unsigned n_reserve;
+
+        assert(u);
+        assert(other);
+        assert(d < _UNIT_DEPENDENCY_MAX);
+
+        /*
+         * If u does not have this dependency set allocated, there is no need
+         * to reserve anything. In that case other's set will be transfered
+         * as a whole to u by complete_move().
+         */
+        if (!u->dependencies[d])
+                return 0;
+
+        /* merge_dependencies() will skip a u-on-u dependency */
+        n_reserve = set_size(other->dependencies[d]) - !!set_get(other->dependencies[d], u);
+
+        return set_reserve(u->dependencies[d], n_reserve);
 }
 
 static void merge_dependencies(Unit *u, Unit *other, const char *other_id, UnitDependency d) {
@@ -618,7 +652,8 @@
         if (back)
                 maybe_warn_about_dependency(u->id, other_id, d);
 
-        complete_move(&u->dependencies[d], &other->dependencies[d]);
+        /* The move cannot fail. The caller must have performed a reservation. */
+        assert_se(complete_move(&u->dependencies[d], &other->dependencies[d]) == 0);
 
         set_free(other->dependencies[d]);
         other->dependencies[d] = NULL;
@@ -627,6 +662,7 @@
 int unit_merge(Unit *u, Unit *other) {
         UnitDependency d;
         const char *other_id = NULL;
+        int r;
 
         assert(u);
         assert(other);
@@ -660,8 +696,21 @@
         if (other->id)
                 other_id = strdupa(other->id);
 
+        /* Make reservations to ensure merge_dependencies() won't fail */
+        for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
+                r = reserve_dependencies(u, other, d);
+                /*
+                 * We don't rollback reservations if we fail. We don't have
+                 * a way to undo reservations. A reservation is not a leak.
+                 */
+                if (r < 0)
+                        return r;
+        }
+
         /* Merge names */
-        merge_names(u, other);
+        r = merge_names(u, other);
+        if (r < 0)
+                return r;
 
         /* Redirect all references */
         while (other->refs)
@@ -874,6 +923,12 @@
         if (u->job_timeout > 0)
                 fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
 
+        if (u->job_timeout_action != FAILURE_ACTION_NONE)
+                fprintf(f, "%s\tJob Timeout Action: %s\n", prefix, failure_action_to_string(u->job_timeout_action));
+
+        if (u->job_timeout_reboot_arg)
+                fprintf(f, "%s\tJob Timeout Reboot Argument: %s\n", prefix, u->job_timeout_reboot_arg);
+
         condition_dump_list(u->conditions, f, prefix);
 
         if (dual_timestamp_is_set(&u->condition_timestamp))
@@ -2713,7 +2768,8 @@
 
 void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) {
         DISABLE_WARNING_FORMAT_NONLITERAL;
-        manager_status_printf(u->manager, false, status, unit_status_msg_format, unit_description(u));
+        manager_status_printf(u->manager, STATUS_TYPE_NORMAL,
+                              status, unit_status_msg_format, unit_description(u));
         REENABLE_WARNING;
 }
 
diff -urN systemd-216/src/core/unit.h systemd-217/src/core/unit.h
--- systemd-216/src/core/unit.h	2014-11-03 09:35:35.993257820 -0800
+++ systemd-217/src/core/unit.h	2014-11-03 09:33:48.504174008 -0800
@@ -41,6 +41,7 @@
 #include "condition.h"
 #include "install.h"
 #include "unit-name.h"
+#include "failure-action.h"
 
 enum UnitActiveState {
         UNIT_ACTIVE,
@@ -112,7 +113,10 @@
         /* JOB_NOP jobs are special and can be installed without disturbing the real job. */
         Job *nop_job;
 
+        /* Job timeout and action to take */
         usec_t job_timeout;
+        FailureAction job_timeout_action;
+        char *job_timeout_reboot_arg;
 
         /* References to this */
         LIST_HEAD(UnitRef, refs);
@@ -127,12 +131,6 @@
         dual_timestamp active_exit_timestamp;
         dual_timestamp inactive_enter_timestamp;
 
-        /* Counterparts in the cgroup filesystem */
-        char *cgroup_path;
-        CGroupControllerMask cgroup_realized_mask;
-        CGroupControllerMask cgroup_subtree_mask;
-        CGroupControllerMask cgroup_members_mask;
-
         UnitRef slice;
 
         /* Per type list */
@@ -176,6 +174,15 @@
         /* Cached unit file state */
         UnitFileState unit_file_state;
 
+        /* Counterparts in the cgroup filesystem */
+        char *cgroup_path;
+        CGroupControllerMask cgroup_realized_mask;
+        CGroupControllerMask cgroup_subtree_mask;
+        CGroupControllerMask cgroup_members_mask;
+
+        /* How to start OnFailure units */
+        JobMode on_failure_job_mode;
+
         /* Garbage collect us we nobody wants or requires us anymore */
         bool stop_when_unneeded;
 
@@ -191,9 +198,6 @@
         /* Allow isolation requests */
         bool allow_isolate;
 
-        /* How to start OnFailure units */
-        JobMode on_failure_job_mode;
-
         /* Ignore this unit when isolating */
         bool ignore_on_isolate;
 
diff -urN systemd-216/src/cryptsetup/cryptsetup-generator.c systemd-217/src/cryptsetup/cryptsetup-generator.c
--- systemd-216/src/cryptsetup/cryptsetup-generator.c	2014-06-30 16:14:21.907375738 -0700
+++ systemd-217/src/cryptsetup/cryptsetup-generator.c	2014-11-03 09:33:48.259171538 -0800
@@ -246,7 +246,12 @@
         }
 
         if (!noauto && !nofail) {
-                r = write_drop_in(arg_dest, name, 90, "device-timeout",
+                _cleanup_free_ char *dmname;
+                dmname = strjoin("dev-mapper-", e, ".device", NULL);
+                if (!dmname)
+                        return log_oom();
+
+                r = write_drop_in(arg_dest, dmname, 90, "device-timeout",
                                   "# Automatically generated by systemd-cryptsetup-generator \n\n"
                                   "[Unit]\nJobTimeoutSec=0");
                 if (r < 0) {
@@ -387,7 +392,7 @@
                                 if (k == 2 && streq(proc_uuid, device + 5)) {
                                         free(options);
                                         options = strdup(p);
-                                        if (!proc_options) {
+                                        if (!options) {
                                                 log_oom();
                                                 goto cleanup;
                                         }
diff -urN systemd-216/src/delta/delta.c systemd-217/src/delta/delta.c
--- systemd-216/src/delta/delta.c	2014-11-03 09:35:31.692214453 -0800
+++ systemd-217/src/delta/delta.c	2014-10-24 09:47:54.837311983 -0700
@@ -159,7 +159,7 @@
 
 static int found_override(const char *top, const char *bottom) {
         _cleanup_free_ char *dest = NULL;
-        int k, r;
+        int k;
         pid_t pid;
 
         assert(top);
@@ -194,10 +194,7 @@
                 _exit(1);
         }
 
-        r = wait_for_terminate(pid, NULL);
-        if (r < 0)
-                log_warning("Failed to wait for diff: %s", strerror(-r));
-
+        wait_for_terminate_and_warn("diff", pid);
         putchar('\n');
 
         return k;
diff -urN systemd-216/src/firstboot/firstboot.c systemd-217/src/firstboot/firstboot.c
--- systemd-216/src/firstboot/firstboot.c	2014-11-03 09:35:35.370251538 -0800
+++ systemd-217/src/firstboot/firstboot.c	2014-10-22 11:30:06.811836941 -0700
@@ -451,9 +451,6 @@
         if (faccessat(AT_FDCWD, etc_machine_id, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                 return 0;
 
-        if (!arg_root)
-                return 0;
-
         if (sd_id128_equal(arg_machine_id, SD_ID128_NULL))
                 return 0;
 
diff -urN systemd-216/src/fsck/fsck.c systemd-217/src/fsck/fsck.c
--- systemd-216/src/fsck/fsck.c	2014-08-04 07:25:24.879170261 -0700
+++ systemd-217/src/fsck/fsck.c	2014-10-22 02:45:36.834211466 -0700
@@ -320,16 +320,11 @@
         cmdline[i++] = "-T";
 
         /*
-         * Disable locking which conflict with udev's event
-         * ownershipi, until util-linux moves the flock
-         * synchronization file which prevents multiple fsck running
-         * on the same rotationg media, from the disk device
-         * node to a privately owned regular file.
-         *
-         * https://bugs.freedesktop.org/show_bug.cgi?id=79576#c5
-         *
-         * cmdline[i++] = "-l";
+         * Since util-linux v2.25 fsck uses /run/fsck/<diskname>.lock files.
+         * The previous versions use flock for the device and conflict with
+         * udevd, see https://bugs.freedesktop.org/show_bug.cgi?id=79576#c5
          */
+        cmdline[i++] = "-l";
 
         if (!root_directory)
                 cmdline[i++] = "-M";
diff -urN systemd-216/src/fstab-generator/fstab-generator.c systemd-217/src/fstab-generator/fstab-generator.c
--- systemd-216/src/fstab-generator/fstab-generator.c	2014-11-03 09:35:37.183269819 -0800
+++ systemd-217/src/fstab-generator/fstab-generator.c	2014-10-28 06:31:25.184131420 -0700
@@ -47,7 +47,6 @@
 static char *arg_usr_fstype = NULL;
 static char *arg_usr_options = NULL;
 
-
 static int mount_find_pri(struct mntent *me, int *ret) {
         char *end, *opt;
         unsigned long r;
@@ -60,7 +59,6 @@
                 return 0;
 
         opt += strlen("pri");
-
         if (*opt != '=')
                 return -EINVAL;
 
@@ -76,43 +74,9 @@
         return 1;
 }
 
-static int mount_find_discard(struct mntent *me, char **ret) {
-        char *opt, *ans;
-        size_t len;
-
-        assert(me);
-        assert(ret);
-
-        opt = hasmntopt(me, "discard");
-        if (!opt)
-                return 0;
-
-        opt += strlen("discard");
-
-        if (*opt == ',' || *opt == '\0')
-                ans = strdup("all");
-        else {
-                if (*opt != '=')
-                        return -EINVAL;
-
-                len = strcspn(opt + 1, ",");
-                if (len == 0)
-                        return -EINVAL;
-
-                ans = strndup(opt + 1, len);
-        }
-
-        if (!ans)
-                return -ENOMEM;
-
-        *ret = ans;
-        return 1;
-}
-
 static int add_swap(const char *what, struct mntent *me) {
         _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
         _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_free_ char *discard = NULL;
 
         bool noauto;
         int r, pri = -1;
@@ -131,12 +95,6 @@
                 return r;
         }
 
-        r = mount_find_discard(me, &discard);
-        if (r < 0) {
-                log_error("Failed to parse discard");
-                return r;
-        }
-
         noauto = !!hasmntopt(me, "noauto");
 
         name = unit_name_from_path(what, ".swap");
@@ -165,16 +123,18 @@
                 "What=%s\n",
                 what);
 
+        /* Note that we currently pass the priority field twice, once
+         * in Priority=, and once in Options= */
         if (pri >= 0)
                 fprintf(f, "Priority=%i\n", pri);
 
-        if (discard)
-                fprintf(f, "Discard=%s\n", discard);
+        if (!isempty(me->mnt_opts) && !streq(me->mnt_opts, "defaults"))
+                fprintf(f, "Options=%s\n", me->mnt_opts);
 
-        fflush(f);
-        if (ferror(f)) {
-                log_error("Failed to write unit file %s: %m", unit);
-                return -errno;
+        r = fflush_and_check(f);
+        if (r < 0) {
+                log_error("Failed to write unit file %s: %s", unit, strerror(-r));
+                return r;
         }
 
         /* use what as where, to have a nicer error message */
diff -urN systemd-216/src/hostname/hostnamed.c systemd-217/src/hostname/hostnamed.c
--- systemd-216/src/hostname/hostnamed.c	2014-11-03 09:35:28.514182408 -0800
+++ systemd-217/src/hostname/hostnamed.c	2014-10-27 04:48:29.292966277 -0700
@@ -287,7 +287,7 @@
         else
                 hn = "localhost";
 
-        if (sethostname(hn, strlen(hn)) < 0)
+        if (sethostname_idempotent(hn) < 0)
                 return -errno;
 
         return 0;
@@ -684,7 +684,7 @@
         log_open();
 
         umask(0022);
-        label_init("/etc");
+        mac_selinux_init("/etc");
 
         if (argc != 1) {
                 log_error("This program takes no arguments.");
diff -urN systemd-216/src/journal/coredump.c systemd-217/src/journal/coredump.c
--- systemd-216/src/journal/coredump.c	2014-08-14 18:10:20.483067226 -0700
+++ systemd-217/src/journal/coredump.c	2014-10-24 04:32:16.035468523 -0700
@@ -673,9 +673,9 @@
 
         /* Now, let's drop privileges to become the user who owns the
          * segfaulted process and allocate the coredump memory under
-         * his uid. This also ensures that the credentials journald
-         * will see are the ones of the coredumping user, thus making
-         * sure the user himself gets access to the core dump. */
+         * the user's uid. This also ensures that the credentials
+         * journald will see are the ones of the coredumping user,
+         * thus making sure the user gets access to the core dump. */
         if (setresgid(gid, gid, gid) < 0 ||
             setresuid(uid, uid, uid) < 0) {
                 log_error("Failed to drop privileges: %m");
diff -urN systemd-216/src/journal/journalctl.c systemd-217/src/journal/journalctl.c
--- systemd-216/src/journal/journalctl.c	2014-11-03 09:35:36.838266340 -0800
+++ systemd-217/src/journal/journalctl.c	2014-10-27 04:48:29.292966277 -0700
@@ -31,8 +31,10 @@
 #include <time.h>
 #include <getopt.h>
 #include <signal.h>
+#include <poll.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
+#include <sys/inotify.h>
 #include <linux/fs.h>
 
 #ifdef HAVE_ACL
@@ -40,7 +42,8 @@
 #include "acl-util.h"
 #endif
 
-#include "systemd/sd-journal.h"
+#include "sd-journal.h"
+#include "sd-bus.h"
 
 #include "log.h"
 #include "logs-show.h"
@@ -59,9 +62,18 @@
 #include "fsprg.h"
 #include "unit-name.h"
 #include "catalog.h"
+#include "mkdir.h"
+#include "bus-util.h"
+#include "bus-error.h"
 
 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
 
+enum {
+        /* Special values for arg_lines */
+        ARG_LINES_DEFAULT = -2,
+        ARG_LINES_ALL = -1,
+};
+
 static OutputMode arg_output = OUTPUT_SHORT;
 static bool arg_utc = false;
 static bool arg_pager_end = false;
@@ -69,7 +81,7 @@
 static bool arg_full = true;
 static bool arg_all = false;
 static bool arg_no_pager = false;
-static int arg_lines = -2;
+static int arg_lines = ARG_LINES_DEFAULT;
 static bool arg_no_tail = false;
 static bool arg_quiet = false;
 static bool arg_merge = false;
@@ -111,6 +123,7 @@
         ACTION_DUMP_CATALOG,
         ACTION_UPDATE_CATALOG,
         ACTION_LIST_BOOTS,
+        ACTION_FLUSH,
 } arg_action = ACTION_SHOW;
 
 typedef struct boot_id_t {
@@ -181,7 +194,7 @@
                "     --user                Show the user journal for the current user\n"
                "  -M --machine=CONTAINER   Operate on local container\n"
                "     --since=DATE          Start showing entries on or newer than the specified date\n"
-               "     --until=DATE          Stop showing entries on or older than the specified date\n"
+               "     --until=DATE          Stop showing entries on or newer than the specified date\n"
                "  -c --cursor=CURSOR       Start showing entries from the specified cursor\n"
                "     --after-cursor=CURSOR Start showing entries from after the specified cursor\n"
                "     --show-cursor         Print the cursor after all the entries\n"
@@ -225,6 +238,7 @@
                "     --list-catalog        Show message IDs of all entries in the message catalog\n"
                "     --dump-catalog        Show entries in the message catalog\n"
                "     --update-catalog      Update the message catalog database\n"
+               "     --flush               Flush all journal data from /run into /var\n"
 #ifdef HAVE_GCRYPT
                "     --setup-keys          Generate a new FSS key pair\n"
                "     --verify              Verify journal file consistency\n"
@@ -261,6 +275,7 @@
                 ARG_UPDATE_CATALOG,
                 ARG_FORCE,
                 ARG_UTC,
+                ARG_FLUSH,
         };
 
         static const struct option options[] = {
@@ -311,6 +326,7 @@
                 { "reverse",        no_argument,       NULL, 'r'                },
                 { "machine",        required_argument, NULL, 'M'                },
                 { "utc",            no_argument,       NULL, ARG_UTC            },
+                { "flush",          no_argument,       NULL, ARG_FLUSH          },
                 {}
         };
 
@@ -339,7 +355,7 @@
                 case 'e':
                         arg_pager_end = true;
 
-                        if (arg_lines < -1)
+                        if (arg_lines == ARG_LINES_DEFAULT)
                                 arg_lines = 1000;
 
                         break;
@@ -379,7 +395,7 @@
                 case 'n':
                         if (optarg) {
                                 if (streq(optarg, "all"))
-                                        arg_lines = -1;
+                                        arg_lines = ARG_LINES_ALL;
                                 else {
                                         r = safe_atoi(optarg, &arg_lines);
                                         if (r < 0 || arg_lines < 0) {
@@ -398,7 +414,7 @@
                                 if (optind < argc) {
                                         int n;
                                         if (streq(argv[optind], "all")) {
-                                                arg_lines = -1;
+                                                arg_lines = ARG_LINES_ALL;
                                                 optind++;
                                         } else if (safe_atoi(argv[optind], &n) >= 0 && n >= 0) {
                                                 arg_lines = n;
@@ -655,6 +671,10 @@
                         arg_utc = true;
                         break;
 
+                case ARG_FLUSH:
+                        arg_action = ACTION_FLUSH;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -662,7 +682,7 @@
                         assert_not_reached("Unhandled option");
                 }
 
-        if (arg_follow && !arg_no_tail && arg_lines < -1)
+        if (arg_follow && !arg_no_tail && arg_lines == ARG_LINES_DEFAULT)
                 arg_lines = 10;
 
         if (!!arg_directory + !!arg_file + !!arg_machine > 1) {
@@ -824,28 +844,32 @@
         return _a < _b ? -1 : (_a > _b ? 1 : 0);
 }
 
-static int list_boots(sd_journal *j) {
+static int get_boots(sd_journal *j,
+                     boot_id_t **boots,
+                     unsigned int *count,
+                     boot_id_t *query_ref_boot) {
         int r;
         const void *data;
-        unsigned int count = 0;
-        int w, i;
         size_t length, allocated = 0;
-        boot_id_t *id;
-        _cleanup_free_ boot_id_t *all_ids = NULL;
+
+        assert(j);
+        assert(boots);
+        assert(count);
 
         r = sd_journal_query_unique(j, "_BOOT_ID");
         if (r < 0)
                 return r;
 
-        pager_open_if_enabled();
-
+        *count = 0;
         SD_JOURNAL_FOREACH_UNIQUE(j, data, length) {
+                boot_id_t *id;
+
                 assert(startswith(data, "_BOOT_ID="));
 
-                if (!GREEDY_REALLOC(all_ids, allocated, count + 1))
+                if (!GREEDY_REALLOC(*boots, allocated, *count + 1))
                         return log_oom();
 
-                id = &all_ids[count];
+                id = *boots + *count;
 
                 r = sd_id128_from_string(((const char *)data) + strlen("_BOOT_ID="), &id->id);
                 if (r < 0)
@@ -869,26 +893,48 @@
                 if (r < 0)
                         return r;
 
-                r = sd_journal_seek_tail(j);
-                if (r < 0)
-                        return r;
+                if (query_ref_boot) {
+                        id->last = 0;
+                        if (sd_id128_equal(id->id, query_ref_boot->id))
+                                *query_ref_boot = *id;
+                } else {
+                        r = sd_journal_seek_tail(j);
+                        if (r < 0)
+                                return r;
 
-                r = sd_journal_previous(j);
-                if (r < 0)
-                        return r;
-                else if (r == 0)
-                        goto flush;
+                        r = sd_journal_previous(j);
+                        if (r < 0)
+                                return r;
+                        else if (r == 0)
+                                goto flush;
 
-                r = sd_journal_get_realtime_usec(j, &id->last);
-                if (r < 0)
-                        return r;
+                        r = sd_journal_get_realtime_usec(j, &id->last);
+                        if (r < 0)
+                                return r;
+                }
 
-                count++;
+                (*count)++;
         flush:
                 sd_journal_flush_matches(j);
         }
 
-        qsort_safe(all_ids, count, sizeof(boot_id_t), boot_id_cmp);
+        qsort_safe(*boots, *count, sizeof(boot_id_t), boot_id_cmp);
+        return 0;
+}
+
+static int list_boots(sd_journal *j) {
+        int r, w, i;
+        unsigned int count;
+        boot_id_t *id;
+        _cleanup_free_ boot_id_t *all_ids = NULL;
+
+        assert(j);
+
+        r = get_boots(j, &all_ids, &count, NULL);
+        if (r < 0)
+                return r;
+
+        pager_open_if_enabled();
 
         /* numbers are one less, but we need an extra char for the sign */
         w = DECIMAL_STR_WIDTH(count - 1) + 1;
@@ -906,76 +952,34 @@
         return 0;
 }
 
-static int get_relative_boot_id(sd_journal *j, sd_id128_t *boot_id, int relative) {
+static int get_boot_id_by_offset(sd_journal *j, sd_id128_t *boot_id, int offset) {
         int r;
-        const void *data;
-        unsigned int count = 0;
-        size_t length, allocated = 0;
-        boot_id_t ref_boot_id = {SD_ID128_NULL}, *id;
+        unsigned int count;
+        boot_id_t ref_boot_id = {}, *id;
         _cleanup_free_ boot_id_t *all_ids = NULL;
 
         assert(j);
         assert(boot_id);
 
-        r = sd_journal_query_unique(j, "_BOOT_ID");
+        ref_boot_id.id = *boot_id;
+        r = get_boots(j, &all_ids, &count, &ref_boot_id);
         if (r < 0)
                 return r;
 
-        SD_JOURNAL_FOREACH_UNIQUE(j, data, length) {
-                if (length < strlen("_BOOT_ID="))
-                        continue;
-
-                if (!GREEDY_REALLOC(all_ids, allocated, count + 1))
-                        return log_oom();
-
-                id = &all_ids[count];
-
-                r = sd_id128_from_string(((const char *)data) + strlen("_BOOT_ID="), &id->id);
-                if (r < 0)
-                        continue;
-
-                r = sd_journal_add_match(j, data, length);
-                if (r < 0)
-                        return r;
-
-                r = sd_journal_seek_head(j);
-                if (r < 0)
-                        return r;
-
-                r = sd_journal_next(j);
-                if (r < 0)
-                        return r;
-                else if (r == 0)
-                        goto flush;
-
-                r = sd_journal_get_realtime_usec(j, &id->first);
-                if (r < 0)
-                        return r;
-
-                if (sd_id128_equal(id->id, *boot_id))
-                        ref_boot_id = *id;
-
-                count++;
-        flush:
-                sd_journal_flush_matches(j);
-        }
-
-        qsort_safe(all_ids, count, sizeof(boot_id_t), boot_id_cmp);
-
         if (sd_id128_equal(*boot_id, SD_ID128_NULL)) {
-                if (relative > (int) count || relative <= -(int)count)
+                if (offset > (int) count || offset <= -(int)count)
                         return -EADDRNOTAVAIL;
 
-                *boot_id = all_ids[(relative <= 0)*count + relative - 1].id;
+                *boot_id = all_ids[(offset <= 0)*count + offset - 1].id;
         } else {
                 id = bsearch(&ref_boot_id, all_ids, count, sizeof(boot_id_t), boot_id_cmp);
 
                 if (!id ||
-                    relative <= 0 ? (id - all_ids) + relative < 0 :
-                                    (id - all_ids) + relative >= (int) count)
+                    offset <= 0 ? (id - all_ids) + offset < 0 :
+                                    (id - all_ids) + offset >= (int) count)
                         return -EADDRNOTAVAIL;
 
-                *boot_id = (id + relative)->id;
+                *boot_id = (id + offset)->id;
         }
 
         return 0;
@@ -993,7 +997,7 @@
         if (arg_boot_offset == 0 && sd_id128_equal(arg_boot_id, SD_ID128_NULL))
                 return add_match_this_boot(j, arg_machine);
 
-        r = get_relative_boot_id(j, &arg_boot_id, arg_boot_offset);
+        r = get_boot_id_by_offset(j, &arg_boot_id, arg_boot_offset);
         if (r < 0) {
                 if (sd_id128_equal(arg_boot_id, SD_ID128_NULL))
                         log_error("Failed to look up boot %+i: %s", arg_boot_offset, strerror(-r));
@@ -1488,7 +1492,7 @@
 
         log_show_color(true);
 
-        HASHMAP_FOREACH(f, j->files, i) {
+        ORDERED_HASHMAP_FOREACH(f, j->files, i) {
                 int k;
                 usec_t first, validated, last;
 
@@ -1583,7 +1587,7 @@
         assert(j);
 
         if (set_isempty(j->errors)) {
-                if (hashmap_isempty(j->files))
+                if (ordered_hashmap_isempty(j->files))
                         log_notice("No journal files were found.");
                 return 0;
         }
@@ -1615,7 +1619,7 @@
                 }
 #endif
 
-                if (hashmap_isempty(j->files)) {
+                if (ordered_hashmap_isempty(j->files)) {
                         log_error("No journal files were opened due to insufficient permissions.");
                         r = -EACCES;
                 }
@@ -1635,6 +1639,77 @@
         return r;
 }
 
+static int flush_to_var(void) {
+        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_bus_close_unref_ sd_bus *bus = NULL;
+        _cleanup_close_ int watch_fd = -1;
+        int r;
+
+        /* Quick exit */
+        if (access("/run/systemd/journal/flushed", F_OK) >= 0)
+                return 0;
+
+        /* OK, let's actually do the full logic, send SIGUSR1 to the
+         * daemon and set up inotify to wait for the flushed file to appear */
+        r = bus_open_system_systemd(&bus);
+        if (r < 0) {
+                log_error("Failed to get D-Bus connection: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_bus_call_method(
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "KillUnit",
+                        &error,
+                        NULL,
+                        "ssi", "systemd-journald.service", "main", SIGUSR1);
+        if (r < 0) {
+                log_error("Failed to kill journal service: %s", bus_error_message(&error, r));
+                return r;
+        }
+
+        mkdir_p("/run/systemd/journal", 0755);
+
+        watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
+        if (watch_fd < 0) {
+                log_error("Failed to create inotify watch: %m");
+                return -errno;
+        }
+
+        r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE|IN_DONT_FOLLOW|IN_ONLYDIR);
+        if (r < 0) {
+                log_error("Failed to watch journal directory: %m");
+                return -errno;
+        }
+
+        for (;;) {
+                if (access("/run/systemd/journal/flushed", F_OK) >= 0)
+                        break;
+
+                if (errno != ENOENT) {
+                        log_error("Failed to check for existance of /run/systemd/journal/flushed: %m");
+                        return -errno;
+                }
+
+                r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
+                if (r < 0) {
+                        log_error("Failed to wait for event: %s", strerror(-r));
+                        return r;
+                }
+
+                r = flush_fd(watch_fd);
+                if (r < 0) {
+                        log_error("Failed to flush inotify events: %s", strerror(-r));
+                        return r;
+                }
+        }
+
+        return 0;
+}
+
 int main(int argc, char *argv[]) {
         int r;
         _cleanup_journal_close_ sd_journal *j = NULL;
@@ -1659,6 +1734,11 @@
                 goto finish;
         }
 
+        if (arg_action == ACTION_FLUSH) {
+                r = flush_to_var();
+                goto finish;
+        }
+
         if (arg_action == ACTION_SETUP_KEYS) {
                 r = setup_keys();
                 goto finish;
diff -urN systemd-216/src/journal/journald-native.c systemd-217/src/journal/journald-native.c
--- systemd-216/src/journal/journald-native.c	2014-08-04 19:14:02.807417077 -0700
+++ systemd-217/src/journal/journald-native.c	2014-10-23 08:20:23.286118525 -0700
@@ -417,7 +417,7 @@
         }
 
 #ifdef HAVE_SELINUX
-        if (use_selinux()) {
+        if (mac_selinux_use()) {
                 one = 1;
                 r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
                 if (r < 0)
diff -urN systemd-216/src/journal/journald-server.c systemd-217/src/journal/journald-server.c
--- systemd-216/src/journal/journald-server.c	2014-11-03 09:35:27.861175824 -0800
+++ systemd-217/src/journal/journald-server.c	2014-10-27 04:48:29.292966277 -0700
@@ -266,7 +266,7 @@
         if (r < 0)
                 return s->system_journal;
 
-        f = hashmap_get(s->user_journals, UINT32_TO_PTR(uid));
+        f = ordered_hashmap_get(s->user_journals, UINT32_TO_PTR(uid));
         if (f)
                 return f;
 
@@ -274,9 +274,9 @@
                      SD_ID128_FORMAT_VAL(machine), uid) < 0)
                 return s->system_journal;
 
-        while (hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
+        while (ordered_hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
                 /* Too many open? Then let's close one */
-                f = hashmap_steal_first(s->user_journals);
+                f = ordered_hashmap_steal_first(s->user_journals);
                 assert(f);
                 journal_file_close(f);
         }
@@ -287,7 +287,7 @@
 
         server_fix_perms(s, f, uid);
 
-        r = hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f);
+        r = ordered_hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f);
         if (r < 0) {
                 journal_file_close(f);
                 return s->system_journal;
@@ -328,13 +328,13 @@
         do_rotate(s, &s->runtime_journal, "runtime", false, 0);
         do_rotate(s, &s->system_journal, "system", s->seal, 0);
 
-        HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
+        ORDERED_HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
                 r = do_rotate(s, &f, "user", s->seal, PTR_TO_UINT32(k));
                 if (r >= 0)
-                        hashmap_replace(s->user_journals, k, f);
+                        ordered_hashmap_replace(s->user_journals, k, f);
                 else if (!f)
                         /* Old file has been closed and deallocated */
-                        hashmap_remove(s->user_journals, k);
+                        ordered_hashmap_remove(s->user_journals, k);
         }
 }
 
@@ -350,7 +350,7 @@
                         log_error("Failed to sync system journal: %s", strerror(-r));
         }
 
-        HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
+        ORDERED_HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
                 r = journal_file_set_offline(f);
                 if (r < 0)
                         log_error("Failed to sync user journal: %s", strerror(-r));
@@ -680,7 +680,7 @@
                 }
 
 #ifdef HAVE_SELINUX
-                if (use_selinux()) {
+                if (mac_selinux_use()) {
                         if (label) {
                                 x = alloca(strlen("_SELINUX_CONTEXT=") + label_len + 1);
 
@@ -919,7 +919,7 @@
 }
 
 
-static int system_journal_open(Server *s) {
+static int system_journal_open(Server *s, bool flush_requested) {
         int r;
         char *fn;
         sd_id128_t machine;
@@ -935,7 +935,8 @@
 
         if (!s->system_journal &&
             (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
-            access("/run/systemd/journal/flushed", F_OK) >= 0) {
+            (flush_requested
+             || access("/run/systemd/journal/flushed", F_OK) >= 0)) {
 
                 /* If in auto mode: first try to create the machine
                  * path, but not the prefix.
@@ -1029,7 +1030,7 @@
         if (!s->runtime_journal)
                 return 0;
 
-        system_journal_open(s);
+        system_journal_open(s, true);
 
         if (!s->system_journal)
                 return 0;
@@ -1221,9 +1222,11 @@
 
         log_info("Received request to flush runtime journal from PID %"PRIu32, si->ssi_pid);
 
-        touch("/run/systemd/journal/flushed");
         server_flush_to_var(s);
         server_sync(s);
+        server_vacuum(s);
+
+        touch("/run/systemd/journal/flushed");
 
         return 0;
 }
@@ -1475,15 +1478,14 @@
         server_parse_config_file(s);
         server_parse_proc_cmdline(s);
         if (!!s->rate_limit_interval ^ !!s->rate_limit_burst) {
-                log_debug("Setting both rate limit interval and burst from %llu,%u to 0,0",
-                          (long long unsigned) s->rate_limit_interval,
-                          s->rate_limit_burst);
+                log_debug("Setting both rate limit interval and burst from "USEC_FMT",%u to 0,0",
+                          s->rate_limit_interval, s->rate_limit_burst);
                 s->rate_limit_interval = s->rate_limit_burst = 0;
         }
 
         mkdir_p("/run/systemd/journal", 0755);
 
-        s->user_journals = hashmap_new(NULL);
+        s->user_journals = ordered_hashmap_new(NULL);
         if (!s->user_journals)
                 return log_oom();
 
@@ -1585,7 +1587,7 @@
         server_cache_boot_id(s);
         server_cache_machine_id(s);
 
-        r = system_journal_open(s);
+        r = system_journal_open(s, false);
         if (r < 0)
                 return r;
 
@@ -1603,7 +1605,7 @@
         if (s->system_journal)
                 journal_file_maybe_append_tag(s->system_journal, n);
 
-        HASHMAP_FOREACH(f, s->user_journals, i)
+        ORDERED_HASHMAP_FOREACH(f, s->user_journals, i)
                 journal_file_maybe_append_tag(f, n);
 #endif
 }
@@ -1621,10 +1623,10 @@
         if (s->runtime_journal)
                 journal_file_close(s->runtime_journal);
 
-        while ((f = hashmap_steal_first(s->user_journals)))
+        while ((f = ordered_hashmap_steal_first(s->user_journals)))
                 journal_file_close(f);
 
-        hashmap_free(s->user_journals);
+        ordered_hashmap_free(s->user_journals);
 
         sd_event_source_unref(s->syslog_event_source);
         sd_event_source_unref(s->native_event_source);
diff -urN systemd-216/src/journal/journald-server.h systemd-217/src/journal/journald-server.h
--- systemd-216/src/journal/journald-server.h	2014-06-19 03:38:45.352239408 -0700
+++ systemd-217/src/journal/journald-server.h	2014-10-23 10:00:37.303180611 -0700
@@ -76,7 +76,7 @@
 
         JournalFile *runtime_journal;
         JournalFile *system_journal;
-        Hashmap *user_journals;
+        OrderedHashmap *user_journals;
 
         uint64_t seqnum;
 
diff -urN systemd-216/src/journal/journald-stream.c systemd-217/src/journal/journald-stream.c
--- systemd-216/src/journal/journald-stream.c	2014-07-21 15:37:55.820843175 -0700
+++ systemd-217/src/journal/journald-stream.c	2014-10-23 08:20:23.306118493 -0700
@@ -395,7 +395,7 @@
         }
 
 #ifdef HAVE_SELINUX
-        if (use_selinux()) {
+        if (mac_selinux_use()) {
                 if (getpeercon(fd, &stream->security_context) < 0 && errno != ENOPROTOOPT)
                         log_error("Failed to determine peer security context: %m");
         }
diff -urN systemd-216/src/journal/journald-syslog.c systemd-217/src/journal/journald-syslog.c
--- systemd-216/src/journal/journald-syslog.c	2014-07-21 15:37:55.820843175 -0700
+++ systemd-217/src/journal/journald-syslog.c	2014-10-23 08:20:23.325118463 -0700
@@ -457,7 +457,7 @@
         }
 
 #ifdef HAVE_SELINUX
-        if (use_selinux()) {
+        if (mac_selinux_use()) {
                 one = 1;
                 r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
                 if (r < 0)
diff -urN systemd-216/src/journal/journal-file.c systemd-217/src/journal/journal-file.c
--- systemd-216/src/journal/journal-file.c	2014-11-03 09:35:36.804265997 -0800
+++ systemd-217/src/journal/journal-file.c	2014-10-27 15:23:05.015526478 -0700
@@ -136,7 +136,7 @@
         if (f->mmap)
                 mmap_cache_unref(f->mmap);
 
-        hashmap_free_free(f->chain_cache);
+        ordered_hashmap_free_free(f->chain_cache);
 
 #if defined(HAVE_XZ) || defined(HAVE_LZ4)
         free(f->compress_buffer);
@@ -1366,7 +1366,7 @@
 } ChainCacheItem;
 
 static void chain_cache_put(
-                Hashmap *h,
+                OrderedHashmap *h,
                 ChainCacheItem *ci,
                 uint64_t first,
                 uint64_t array,
@@ -1380,9 +1380,10 @@
                 if (array == first)
                         return;
 
-                if (hashmap_size(h) >= CHAIN_CACHE_MAX)
-                        ci = hashmap_steal_first(h);
-                else {
+                if (ordered_hashmap_size(h) >= CHAIN_CACHE_MAX) {
+                        ci = ordered_hashmap_steal_first(h);
+                        assert(ci);
+                } else {
                         ci = new(ChainCacheItem, 1);
                         if (!ci)
                                 return;
@@ -1390,7 +1391,7 @@
 
                 ci->first = first;
 
-                if (hashmap_put(h, &ci->first, ci) < 0) {
+                if (ordered_hashmap_put(h, &ci->first, ci) < 0) {
                         free(ci);
                         return;
                 }
@@ -1419,7 +1420,7 @@
         a = first;
 
         /* Try the chain cache first */
-        ci = hashmap_get(f->chain_cache, &first);
+        ci = ordered_hashmap_get(f->chain_cache, &first);
         if (ci && i > ci->total) {
                 a = ci->array;
                 i -= ci->total;
@@ -1522,7 +1523,7 @@
         /* Start with the first array in the chain */
         a = first;
 
-        ci = hashmap_get(f->chain_cache, &first);
+        ci = ordered_hashmap_get(f->chain_cache, &first);
         if (ci && n > ci->total) {
                 /* Ah, we have iterated this bisection array chain
                  * previously! Let's see if we can skip ahead in the
@@ -2498,7 +2499,7 @@
                 goto fail;
         }
 
-        f->chain_cache = hashmap_new(&uint64_hash_ops);
+        f->chain_cache = ordered_hashmap_new(&uint64_hash_ops);
         if (!f->chain_cache) {
                 r = -ENOMEM;
                 goto fail;
diff -urN systemd-216/src/journal/journal-file.h systemd-217/src/journal/journal-file.h
--- systemd-216/src/journal/journal-file.h	2014-11-03 09:35:36.805266007 -0800
+++ systemd-217/src/journal/journal-file.h	2014-10-23 10:00:37.301180489 -0700
@@ -76,7 +76,7 @@
         JournalMetrics metrics;
         MMapCache *mmap;
 
-        Hashmap *chain_cache;
+        OrderedHashmap *chain_cache;
 
 #if defined(HAVE_XZ) || defined(HAVE_LZ4)
         void *compress_buffer;
diff -urN systemd-216/src/journal/journal-internal.h systemd-217/src/journal/journal-internal.h
--- systemd-216/src/journal/journal-internal.h	2014-11-03 09:35:36.731265261 -0800
+++ systemd-217/src/journal/journal-internal.h	2014-10-23 10:00:37.302180550 -0700
@@ -100,7 +100,7 @@
         char *path;
         char *prefix;
 
-        Hashmap *files;
+        OrderedHashmap *files;
         MMapCache *mmap;
 
         Location current_location;
diff -urN systemd-216/src/journal/sd-journal.c systemd-217/src/journal/sd-journal.c
--- systemd-216/src/journal/sd-journal.c	2014-11-03 09:35:36.806266017 -0800
+++ systemd-217/src/journal/sd-journal.c	2014-10-23 10:00:37.304180671 -0700
@@ -86,7 +86,7 @@
         j->current_file = NULL;
         j->current_field = 0;
 
-        HASHMAP_FOREACH(f, j->files, i)
+        ORDERED_HASHMAP_FOREACH(f, j->files, i)
                 f->current_offset = 0;
 }
 
@@ -849,10 +849,8 @@
                         int k;
 
                         k = compare_with_location(f, c, &j->current_location);
-                        if (direction == DIRECTION_DOWN)
-                                found = k > 0;
-                        else
-                                found = k < 0;
+
+                        found = direction == DIRECTION_DOWN ? k > 0 : k < 0;
                 } else
                         found = true;
 
@@ -881,7 +879,7 @@
         assert_return(j, -EINVAL);
         assert_return(!journal_pid_changed(j), -ECHILD);
 
-        HASHMAP_FOREACH(f, j->files, i) {
+        ORDERED_HASHMAP_FOREACH(f, j->files, i) {
                 bool found;
 
                 r = next_beyond_location(j, f, direction, &o, &p);
@@ -1290,10 +1288,10 @@
         assert(j);
         assert(path);
 
-        if (hashmap_get(j->files, path))
+        if (ordered_hashmap_get(j->files, path))
                 return 0;
 
-        if (hashmap_size(j->files) >= JOURNAL_FILES_MAX) {
+        if (ordered_hashmap_size(j->files) >= JOURNAL_FILES_MAX) {
                 log_warning("Too many open journal files, not adding %s.", path);
                 return set_put_error(j, -ETOOMANYREFS);
         }
@@ -1304,7 +1302,7 @@
 
         /* journal_file_dump(f); */
 
-        r = hashmap_put(j->files, f->path, f);
+        r = ordered_hashmap_put(j->files, f->path, f);
         if (r < 0) {
                 journal_file_close(f);
                 return r;
@@ -1353,7 +1351,7 @@
         if (!path)
                 return -ENOMEM;
 
-        f = hashmap_get(j->files, path);
+        f = ordered_hashmap_get(j->files, path);
         if (!f)
                 return 0;
 
@@ -1365,7 +1363,7 @@
         assert(j);
         assert(f);
 
-        hashmap_remove(j->files, f->path);
+        ordered_hashmap_remove(j->files, f->path);
 
         log_debug("File %s removed.", f->path);
 
@@ -1376,7 +1374,7 @@
 
         if (j->unique_file == f) {
                 /* Jump to the next unique_file or NULL if that one was last */
-                j->unique_file = hashmap_next(j->files, j->unique_file->path);
+                j->unique_file = ordered_hashmap_next(j->files, j->unique_file->path);
                 j->unique_offset = 0;
                 if (!j->unique_file)
                         j->unique_file_lost = true;
@@ -1636,7 +1634,7 @@
          * "root" directories. We don't expect errors here, so we
          * treat them as fatal. */
 
-        HASHMAP_FOREACH(f, j->files, i) {
+        ORDERED_HASHMAP_FOREACH(f, j->files, i) {
                 _cleanup_free_ char *dir;
                 int r;
 
@@ -1691,7 +1689,7 @@
                         goto fail;
         }
 
-        j->files = hashmap_new(&string_hash_ops);
+        j->files = ordered_hashmap_new(&string_hash_ops);
         j->directories_by_path = hashmap_new(&string_hash_ops);
         j->mmap = mmap_cache_new();
         if (!j->files || !j->directories_by_path || !j->mmap)
@@ -1737,7 +1735,7 @@
         assert_return(machine, -EINVAL);
         assert_return(ret, -EINVAL);
         assert_return((flags & ~(SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM)) == 0, -EINVAL);
-        assert_return(filename_is_safe(machine), -EINVAL);
+        assert_return(machine_name_is_valid(machine), -EINVAL);
 
         p = strappenda("/run/systemd/machines/", machine);
         r = parse_env_file(p, NEWLINE, "ROOT", &root, "CLASS", &class, NULL);
@@ -1837,10 +1835,10 @@
 
         sd_journal_flush_matches(j);
 
-        while ((f = hashmap_steal_first(j->files)))
+        while ((f = ordered_hashmap_steal_first(j->files)))
                 journal_file_close(f);
 
-        hashmap_free(j->files);
+        ordered_hashmap_free(j->files);
 
         while ((d = hashmap_first(j->directories_by_path)))
                 remove_directory(j, d);
@@ -2370,7 +2368,7 @@
         assert_return(from || to, -EINVAL);
         assert_return(from != to, -EINVAL);
 
-        HASHMAP_FOREACH(f, j->files, i) {
+        ORDERED_HASHMAP_FOREACH(f, j->files, i) {
                 usec_t fr, t;
 
                 r = journal_file_get_cutoff_realtime_usec(f, &fr, &t);
@@ -2410,7 +2408,7 @@
         assert_return(from || to, -EINVAL);
         assert_return(from != to, -EINVAL);
 
-        HASHMAP_FOREACH(f, j->files, i) {
+        ORDERED_HASHMAP_FOREACH(f, j->files, i) {
                 usec_t fr, t;
 
                 r = journal_file_get_cutoff_monotonic_usec(f, boot_id, &fr, &t);
@@ -2445,7 +2443,7 @@
 
         assert(j);
 
-        HASHMAP_FOREACH(f, j->files, i) {
+        ORDERED_HASHMAP_FOREACH(f, j->files, i) {
                 if (newline)
                         putchar('\n');
                 else
@@ -2464,7 +2462,7 @@
         assert_return(!journal_pid_changed(j), -ECHILD);
         assert_return(bytes, -EINVAL);
 
-        HASHMAP_FOREACH(f, j->files, i) {
+        ORDERED_HASHMAP_FOREACH(f, j->files, i) {
                 struct stat st;
 
                 if (fstat(f->fd, &st) < 0)
@@ -2513,7 +2511,7 @@
                 if (j->unique_file_lost)
                         return 0;
 
-                j->unique_file = hashmap_first(j->files);
+                j->unique_file = ordered_hashmap_first(j->files);
                 if (!j->unique_file)
                         return 0;
 
@@ -2547,7 +2545,7 @@
 
                 /* We reached the end of the list? Then start again, with the next file */
                 if (j->unique_offset == 0) {
-                        j->unique_file = hashmap_next(j->files, j->unique_file->path);
+                        j->unique_file = ordered_hashmap_next(j->files, j->unique_file->path);
                         if (!j->unique_file)
                                 return 0;
 
@@ -2596,7 +2594,7 @@
                  * object by checking if it exists in the earlier
                  * traversed files. */
                 found = false;
-                HASHMAP_FOREACH(of, j->files, i) {
+                ORDERED_HASHMAP_FOREACH(of, j->files, i) {
                         Object *oo;
                         uint64_t op;
 
diff -urN systemd-216/src/journal-remote/journal-remote.c systemd-217/src/journal-remote/journal-remote.c
--- systemd-216/src/journal-remote/journal-remote.c	2014-11-03 09:35:32.516222761 -0800
+++ systemd-217/src/journal-remote/journal-remote.c	2014-10-23 08:06:27.947110170 -0700
@@ -311,6 +311,8 @@
         Writer *writer;
         int r;
 
+        /* This takes ownership of name, but only on success. */
+
         assert(fd >= 0);
         assert(source);
 
@@ -360,6 +362,8 @@
         RemoteSource *source;
         int r;
 
+        /* This takes ownership of name, even on failure, if own_name is true. */
+
         assert(s);
         assert(fd >= 0);
         assert(name);
@@ -374,6 +378,7 @@
         if (r < 0) {
                 log_error("Failed to create source for fd:%d (%s): %s",
                           fd, name, strerror(-r));
+                free(name);
                 return r;
         }
 
@@ -393,6 +398,12 @@
                 goto error;
         }
 
+        r = sd_event_source_set_name(source->event, name);
+        if (r < 0) {
+                log_error("Failed to set source name for fd:%d: %s", fd, strerror(-r));
+                goto error;
+        }
+
         return 1; /* work to do */
 
  error:
@@ -402,15 +413,24 @@
 
 static int add_raw_socket(RemoteServer *s, int fd) {
         int r;
+        _cleanup_close_ int fd_ = fd;
+        char name[strlen("raw-socket-") + DECIMAL_STR_MAX(int)];
+
+        assert(fd >= 0);
 
         r = sd_event_add_io(s->events, &s->listen_event,
                             fd, EPOLLIN,
                             dispatch_raw_connection_event, s);
-        if (r < 0) {
-                close(fd);
+        if (r < 0)
                 return r;
-        }
 
+        snprintf(name, sizeof(name), "raw-socket-%d", fd);
+
+        r = sd_event_source_set_name(s->listen_event, name);
+        if (r < 0)
+                return r;
+
+        fd_ = -1;
         s->active ++;
         return 0;
 }
@@ -429,33 +449,32 @@
  **********************************************************************
  **********************************************************************/
 
-static RemoteSource *request_meta(void **connection_cls, int fd, char *hostname) {
+static int request_meta(void **connection_cls, int fd, char *hostname) {
         RemoteSource *source;
         Writer *writer;
         int r;
 
         assert(connection_cls);
         if (*connection_cls)
-                return *connection_cls;
+                return 0;
 
         r = get_writer(server, hostname, &writer);
         if (r < 0) {
                 log_warning("Failed to get writer for source %s: %s",
                             hostname, strerror(-r));
-                return NULL;
+                return r;
         }
 
         source = source_new(fd, true, hostname, writer);
         if (!source) {
-                log_oom();
                 writer_unref(writer);
-                return NULL;
+                return log_oom();
         }
 
         log_debug("Added RemoteSource as connection metadata %p", source);
 
         *connection_cls = source;
-        return source;
+        return 0;
 }
 
 static void request_meta_free(void *cls,
@@ -467,9 +486,11 @@
         assert(connection_cls);
         s = *connection_cls;
 
-        log_debug("Cleaning up connection metadata %p", s);
-        source_free(s);
-        *connection_cls = NULL;
+        if (s) {
+                log_debug("Cleaning up connection metadata %p", s);
+                source_free(s);
+                *connection_cls = NULL;
+        }
 }
 
 static int process_http_upload(
@@ -484,11 +505,11 @@
 
         assert(source);
 
-        log_debug("request_handler_upload: connection %p, %zu bytes",
-                  connection, *upload_data_size);
+        log_trace("%s: connection %p, %zu bytes",
+                  __func__, connection, *upload_data_size);
 
         if (*upload_data_size) {
-                log_debug("Received %zu bytes", *upload_data_size);
+                log_trace("Received %zu bytes", *upload_data_size);
 
                 r = push_data(source, upload_data, *upload_data_size);
                 if (r < 0)
@@ -551,7 +572,7 @@
         assert(url);
         assert(method);
 
-        log_debug("Handling a connection %s %s %s", method, url, version);
+        log_trace("Handling a connection %s %s %s", method, url, version);
 
         if (*connection_cls)
                 return process_http_upload(connection,
@@ -602,8 +623,13 @@
 
         assert(hostname);
 
-        if (!request_meta(connection_cls, fd, hostname))
+        r = request_meta(connection_cls, fd, hostname);
+        if (r == -ENOMEM)
                 return respond_oom(connection);
+        else if (r < 0)
+                return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                   strerror(-r));
+
         hostname = NULL;
         return MHD_YES;
 }
@@ -698,6 +724,12 @@
                 goto error;
         }
 
+        r = sd_event_source_set_name(d->event, "epoll-fd");
+        if (r < 0) {
+                log_error("Failed to set source name: %s", strerror(-r));
+                goto error;
+        }
+
         r = hashmap_ensure_allocated(&s->daemons, &uint64_hash_ops);
         if (r < 0) {
                 log_oom();
@@ -757,19 +789,6 @@
  **********************************************************************
  **********************************************************************/
 
-static int dispatch_sigterm(sd_event_source *event,
-                            const struct signalfd_siginfo *si,
-                            void *userdata) {
-        RemoteServer *s = userdata;
-
-        assert(s);
-
-        log_received_signal(LOG_INFO, si);
-
-        sd_event_exit(s->events, 0);
-        return 0;
-}
-
 static int setup_signals(RemoteServer *s) {
         sigset_t mask;
         int r;
@@ -780,27 +799,38 @@
         sigset_add_many(&mask, SIGINT, SIGTERM, -1);
         assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
 
-        r = sd_event_add_signal(s->events, &s->sigterm_event, SIGTERM, dispatch_sigterm, s);
+        r = sd_event_add_signal(s->events, &s->sigterm_event, SIGTERM, NULL, s);
+        if (r < 0)
+                return r;
+
+        r = sd_event_source_set_name(s->sigterm_event, "sigterm");
+        if (r < 0)
+                return r;
+
+        r = sd_event_add_signal(s->events, &s->sigint_event, SIGINT, NULL, s);
         if (r < 0)
                 return r;
 
-        r = sd_event_add_signal(s->events, &s->sigint_event, SIGINT, dispatch_sigterm, s);
+        r = sd_event_source_set_name(s->sigint_event, "sigint");
         if (r < 0)
                 return r;
 
         return 0;
 }
 
-static int fd_fd(const char *spec) {
+static int negative_fd(const char *spec) {
+        /* Return a non-positive number as its inverse, -EINVAL otherwise. */
+
         int fd, r;
 
         r = safe_atoi(spec, &fd);
         if (r < 0)
                 return r;
-        if (fd < 0)
-                return -EINVAL;
 
-        return fd;
+        if (fd > 0)
+                return -EINVAL;
+        else
+                return -fd;
 }
 
 static int remoteserver_init(RemoteServer *s,
@@ -846,7 +876,7 @@
         }
 
         for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
-                if (sd_is_socket(fd, AF_UNSPEC, 0, false)) {
+                if (sd_is_socket(fd, AF_UNSPEC, 0, true)) {
                         log_info("Received a listening socket (fd:%d)", fd);
 
                         if (fd == http_socket)
@@ -855,7 +885,7 @@
                                 r = setup_microhttpd_server(s, fd, key, cert, trust);
                         else
                                 r = add_raw_socket(s, fd);
-                } else if (sd_is_socket(fd, AF_UNSPEC, 0, true)) {
+                } else if (sd_is_socket(fd, AF_UNSPEC, 0, false)) {
                         char *hostname;
 
                         r = getnameinfo_pretty(fd, &hostname);
@@ -867,8 +897,6 @@
                         log_info("Received a connection socket (fd:%d) from %s", fd, hostname);
 
                         r = add_source(s, fd, hostname, true);
-                        if (r < 0)
-                                free(hostname);
                 } else {
                         log_error("Unknown socket passed on fd:%d", fd);
 
@@ -1098,7 +1126,7 @@
                                          uint32_t revents,
                                          void *userdata) {
         RemoteServer *s = userdata;
-        int fd2, r;
+        int fd2;
         SocketAddress addr = {
                 .size = sizeof(union sockaddr_union),
                 .type = SOCK_STREAM,
@@ -1109,10 +1137,7 @@
         if (fd2 < 0)
                 return fd2;
 
-        r = add_source(s, fd2, hostname, true);
-        if (r < 0)
-                free(hostname);
-        return r;
+        return add_source(s, fd2, hostname, true);
 }
 
 /**********************************************************************
@@ -1147,24 +1172,25 @@
 static void help(void) {
         printf("%s [OPTIONS...] {FILE|-}...\n\n"
                "Write external journal events to journal file(s).\n\n"
-               "  -h --help               Show this help\n"
-               "     --version            Show package version\n"
-               "     --url=URL            Read events from systemd-journal-gatewayd at URL\n"
-               "     --getter=COMMAND     Read events from the output of COMMAND\n"
-               "     --listen-raw=ADDR    Listen for connections at ADDR\n"
-               "     --listen-http=ADDR   Listen for HTTP connections at ADDR\n"
-               "     --listen-https=ADDR  Listen for HTTPS connections at ADDR\n"
-               "  -o --output=FILE|DIR Write output to FILE or DIR/external-*.journal\n"
-               "     --compress[=BOOL]    Use XZ-compression in the output journal (default: yes)\n"
-               "     --seal[=BOOL]        Use Event sealing in the output journal (default: no)\n"
-               "     --key=FILENAME       Specify key in PEM format (default:\n"
-               "                          \"" PRIV_KEY_FILE "\")\n"
-               "     --cert=FILENAME      Specify certificate in PEM format (default:\n"
-               "                          \"" CERT_FILE "\")\n"
-               "     --trust=FILENAME|all Specify CA certificate or disable checking (default:\n"
-               "                          \"" TRUST_FILE "\")\n"
+               "  -h --help                 Show this help\n"
+               "     --version              Show package version\n"
+               "     --url=URL              Read events from systemd-journal-gatewayd at URL\n"
+               "     --getter=COMMAND       Read events from the output of COMMAND\n"
+               "     --listen-raw=ADDR      Listen for connections at ADDR\n"
+               "     --listen-http=ADDR     Listen for HTTP connections at ADDR\n"
+               "     --listen-https=ADDR    Listen for HTTPS connections at ADDR\n"
+               "  -o --output=FILE|DIR      Write output to FILE or DIR/external-*.journal\n"
+               "     --compress[=BOOL]      XZ-compress the output journal (default: yes)\n"
+               "     --seal[=BOOL]          Use event sealing (default: no)\n"
+               "     --key=FILENAME         SSL key in PEM format (default:\n"
+               "                            \"" PRIV_KEY_FILE "\")\n"
+               "     --cert=FILENAME        SSL certificate in PEM format (default:\n"
+               "                            \"" CERT_FILE "\")\n"
+               "     --trust=FILENAME|all   SSL CA certificate or disable checking (default:\n"
+               "                            \"" TRUST_FILE "\")\n"
                "     --gnutls-log=CATEGORY...\n"
-               "                          Specify a list of gnutls logging categories\n"
+               "                            Specify a list of gnutls logging categories\n"
+               "     --split-mode=none|host How many output files to create\n"
                "\n"
                "Note: file descriptors from sd_listen_fds() will be consumed, too.\n"
                , program_invocation_short_name);
@@ -1256,7 +1282,7 @@
                                 return -EINVAL;
                         }
 
-                        r = fd_fd(optarg);
+                        r = negative_fd(optarg);
                         if (r >= 0)
                                 http_socket = r;
                         else
@@ -1269,7 +1295,7 @@
                                 return -EINVAL;
                         }
 
-                        r = fd_fd(optarg);
+                        r = negative_fd(optarg);
                         if (r >= 0)
                                 https_socket = r;
                         else
@@ -1522,7 +1548,11 @@
         if (remoteserver_init(&s, key, cert, trust) < 0)
                 return EXIT_FAILURE;
 
-        sd_event_set_watchdog(s.events, true);
+        r = sd_event_set_watchdog(s.events, true);
+        if (r < 0)
+                log_error("Failed to enable watchdog: %s", strerror(-r));
+        else
+                log_debug("Watchdog is %s.", r > 0 ? "enabled" : "disabled");
 
         log_debug("%s running as pid "PID_FMT,
                   program_invocation_short_name, getpid());
diff -urN systemd-216/src/journal-remote/journal-remote-parse.c systemd-217/src/journal-remote/journal-remote-parse.c
--- systemd-216/src/journal-remote/journal-remote-parse.c	2014-11-03 09:35:31.771215249 -0800
+++ systemd-217/src/journal-remote/journal-remote-parse.c	2014-10-23 08:06:27.946110177 -0700
@@ -330,7 +330,7 @@
                 assert(line[n-1] == '\n');
 
                 if (n == 1) {
-                        log_debug("Received empty line, event is ready");
+                        log_trace("Received empty line, event is ready");
                         return 1;
                 }
 
@@ -350,7 +350,7 @@
                 else
                         /* replace \n with = */
                         line[n-1] = '=';
-                log_debug("Received: %.*s", (int) n, line);
+                log_trace("Received: %.*s", (int) n, line);
 
                 r = iovw_put(&source->iovw, line, n);
                 if (r < 0) {
@@ -438,7 +438,7 @@
                 return r;
 
         /* We have a full event */
-        log_debug("Received a full event from source@%p fd:%d (%s)",
+        log_trace("Received a full event from source@%p fd:%d (%s)",
                   source, source->fd, source->name);
 
         if (!source->iovw.count) {
diff -urN systemd-216/src/journal-remote/journal-upload.c systemd-217/src/journal-remote/journal-upload.c
--- systemd-216/src/journal-remote/journal-upload.c	2014-11-03 09:35:29.505192401 -0800
+++ systemd-217/src/journal-remote/journal-upload.c	2014-10-23 08:06:27.947110170 -0700
@@ -31,12 +31,14 @@
 #include "util.h"
 #include "build.h"
 #include "fileio.h"
+#include "mkdir.h"
 #include "conf-parser.h"
 #include "journal-upload.h"
 
 #define PRIV_KEY_FILE CERTIFICATE_ROOT "/private/journal-upload.pem"
 #define CERT_FILE     CERTIFICATE_ROOT "/certs/journal-upload.pem"
 #define TRUST_FILE    CERTIFICATE_ROOT "/ca/trusted.pem"
+#define DEFAULT_PORT  19532
 
 static const char* arg_url;
 
@@ -61,7 +63,7 @@
 #define STATE_FILE "/var/lib/systemd/journal-upload/state"
 
 #define easy_setopt(curl, opt, value, level, cmd)                       \
-        {                                                               \
+        do {                                                            \
                 code = curl_easy_setopt(curl, opt, value);              \
                 if (code) {                                             \
                         log_full(level,                                 \
@@ -69,7 +71,7 @@
                                   curl_easy_strerror(code));            \
                         cmd;                                            \
                 }                                                       \
-        }
+        } while(0)
 
 static size_t output_callback(char *buf,
                               size_t size,
@@ -92,6 +94,32 @@
         return size * nmemb;
 }
 
+static int check_cursor_updating(Uploader *u) {
+        _cleanup_free_ char *temp_path = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        int r;
+
+        if (!u->state_file)
+                return 0;
+
+        r = mkdir_parents(u->state_file, 0755);
+        if (r < 0) {
+                log_error("Cannot create parent directory of state file %s: %s",
+                          u->state_file, strerror(-r));
+                return r;
+        }
+
+        r = fopen_temporary(u->state_file, &f, &temp_path);
+        if (r < 0) {
+                log_error("Cannot save state to %s: %s",
+                          u->state_file, strerror(-r));
+                return r;
+        }
+        unlink(temp_path);
+
+        return 0;
+}
+
 static int update_cursor_state(Uploader *u) {
         _cleanup_free_ char *temp_path = NULL;
         _cleanup_fclose_ FILE *f = NULL;
@@ -134,11 +162,14 @@
                            "LAST_CURSOR",  &u->last_cursor,
                            NULL);
 
-        if (r < 0 && r != -ENOENT) {
+        if (r == -ENOENT)
+                log_debug("State file %s is not present.", u->state_file);
+        else if (r < 0) {
                 log_error("Failed to read state file %s: %s",
                           u->state_file, strerror(-r));
                 return r;
-        }
+        } else
+                log_debug("Last cursor was %s", u->last_cursor);
 
         return 0;
 }
@@ -220,15 +251,16 @@
                             LOG_WARNING, );
 
                 if (arg_key || startswith(u->url, "https://")) {
-                        assert(arg_cert);
-
                         easy_setopt(curl, CURLOPT_SSLKEY, arg_key ?: PRIV_KEY_FILE,
                                     LOG_ERR, return -EXFULL);
                         easy_setopt(curl, CURLOPT_SSLCERT, arg_cert ?: CERT_FILE,
                                     LOG_ERR, return -EXFULL);
                 }
 
-                if (arg_trust || startswith(u->url, "https://"))
+                if (streq_ptr(arg_trust, "all"))
+                        easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0,
+                                    LOG_ERR, return -EUCLEAN);
+                else if (arg_trust || startswith(u->url, "https://"))
                         easy_setopt(curl, CURLOPT_CAINFO, arg_trust ?: TRUST_FILE,
                                     LOG_ERR, return -EXFULL);
 
@@ -394,6 +426,7 @@
 
 static int setup_uploader(Uploader *u, const char *url, const char *state_file) {
         int r;
+        const char *host, *proto = "";
 
         assert(u);
         assert(url);
@@ -401,10 +434,24 @@
         memzero(u, sizeof(Uploader));
         u->input = -1;
 
-        if (!startswith(url, "http://") && !startswith(url, "https://"))
-                url = strappenda("https://", url);
+        if (!(host = startswith(url, "http://")) && !(host = startswith(url, "https://"))) {
+                host = url;
+                proto = "https://";
+        }
+
+        if (strchr(host, ':'))
+                u->url = strjoin(proto, url, "/upload", NULL);
+        else {
+                char *t;
+                size_t x;
+
+                t = strdupa(url);
+                x = strlen(t);
+                while (x > 0 && t[x - 1] == '/')
+                        t[x - 1] = '\0';
 
-        u->url = strappend(url, "/upload");
+                u->url = strjoin(proto, t, ":" STRINGIFY(DEFAULT_PORT), "/upload", NULL);
+        }
         if (!u->url)
                 return log_oom();
 
@@ -455,10 +502,12 @@
 
         code = curl_easy_perform(u->easy);
         if (code) {
-                log_error("Upload to %s failed: %.*s",
-                          u->url,
-                          u->error[0] ? (int) sizeof(u->error) : INT_MAX,
-                          u->error[0] ? u->error : curl_easy_strerror(code));
+                if (u->error[0])
+                        log_error("Upload to %s failed: %.*s",
+                                  u->url, (int) sizeof(u->error), u->error);
+                else
+                        log_error("Upload to %s failed: %s",
+                                  u->url, curl_easy_strerror(code));
                 return -EIO;
         }
 
@@ -507,10 +556,14 @@
                "Upload journal events to a remote server.\n\n"
                "  -h --help                 Show this help\n"
                "     --version              Show package version\n"
-               "  -u --url=URL              Upload to this address\n"
-               "     --key=FILENAME         Specify key in PEM format\n"
-               "     --cert=FILENAME        Specify certificate in PEM format\n"
-               "     --trust=FILENAME       Specify CA certificate in PEM format\n"
+               "  -u --url=URL              Upload to this address (default port "
+                                            STRINGIFY(DEFAULT_PORT) ")\n"
+               "     --key=FILENAME         Specify key in PEM format (default:\n"
+               "                            \"" PRIV_KEY_FILE "\")\n"
+               "     --cert=FILENAME        Specify certificate in PEM format (default:\n"
+               "                            \"" CERT_FILE "\")\n"
+               "     --trust=FILENAME|all   Specify CA certificate or disable checking (default:\n"
+               "                            \"" TRUST_FILE "\")\n"
                "     --system               Use the system journal\n"
                "     --user                 Use the user journal for the current user\n"
                "  -m --merge                Use  all available journals\n"
@@ -761,6 +814,10 @@
 
         sd_event_set_watchdog(u.events, true);
 
+        r = check_cursor_updating(&u);
+        if (r < 0)
+                goto cleanup;
+
         log_debug("%s running as pid "PID_FMT,
                   program_invocation_short_name, getpid());
 
@@ -783,6 +840,12 @@
                   "STATUS=Processing input...");
 
         while (true) {
+                r = sd_event_get_state(u.events);
+                if (r < 0)
+                        break;
+                if (r == SD_EVENT_FINISHED)
+                        break;
+
                 if (use_journal) {
                         if (!u.journal)
                                 break;
@@ -798,12 +861,6 @@
                 if (r < 0)
                         goto cleanup;
 
-                r = sd_event_get_state(u.events);
-                if (r < 0)
-                        break;
-                if (r == SD_EVENT_FINISHED)
-                        break;
-
                 if (u.uploading) {
                         r = perform_upload(&u);
                         if (r < 0)
@@ -825,5 +882,5 @@
         destroy_uploader(&u);
 
 finish:
-        return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+        return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff -urN systemd-216/src/kernel-install/90-loaderentry.install systemd-217/src/kernel-install/90-loaderentry.install
--- systemd-216/src/kernel-install/90-loaderentry.install	2014-08-15 07:42:14.307488958 -0700
+++ systemd-217/src/kernel-install/90-loaderentry.install	2014-11-03 09:33:49.152180542 -0800
@@ -47,7 +47,7 @@
 fi
 
 if ! [[ ${BOOT_OPTIONS[*]} ]]; then
-    read -ar line < /proc/cmdline
+    read -a line -r < /proc/cmdline
     for i in "${line[@]}"; do
         [[ "${i#initrd=*}" != "$i" ]] && continue
         BOOT_OPTIONS[${#BOOT_OPTIONS[@]}]="$i"
diff -urN systemd-216/src/libsystemd/libsystemd.sym.m4 systemd-217/src/libsystemd/libsystemd.sym.m4
--- systemd-216/src/libsystemd/libsystemd.sym.m4	2014-11-03 09:35:30.992207394 -0800
+++ systemd-217/src/libsystemd/libsystemd.sym.m4	2014-10-22 11:30:06.645837637 -0700
@@ -191,7 +191,7 @@
         sd_bus_is_open;
         sd_bus_can_send;
         sd_bus_get_server_id;
-        sd_bus_get_peer_creds;
+        sd_bus_get_owner_creds;
         sd_bus_get_name;
         sd_bus_send;
         sd_bus_send_to;
@@ -287,8 +287,8 @@
         sd_bus_request_name;
         sd_bus_release_name;
         sd_bus_list_names;
-        sd_bus_get_owner;
-        sd_bus_get_owner_machine_id;
+        sd_bus_get_name_creds;
+        sd_bus_get_name_machine_id;
         sd_bus_call_method;
         sd_bus_get_property;
         sd_bus_get_property_trivial;
diff -urN systemd-216/src/libsystemd/sd-bus/bus-control.c systemd-217/src/libsystemd/sd-bus/bus-control.c
--- systemd-216/src/libsystemd/sd-bus/bus-control.c	2014-11-03 09:35:37.159269577 -0800
+++ systemd-217/src/libsystemd/sd-bus/bus-control.c	2014-10-27 10:09:26.606862015 -0700
@@ -169,7 +169,7 @@
         if (r < 0)
                 return -errno;
 
-        return n->flags;
+        return 0;
 }
 
 static int bus_release_name_dbus1(sd_bus *bus, const char *name) {
@@ -243,7 +243,7 @@
 static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
         struct kdbus_cmd_name_list cmd = {};
         struct kdbus_name_list *name_list;
-        struct kdbus_cmd_name *name;
+        struct kdbus_name_info *name;
         uint64_t previous_id = 0;
         int r;
 
@@ -265,12 +265,14 @@
                 if ((flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != previous_id) {
                         char *n;
 
-                        if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0)
-                                return -ENOMEM;
+                        if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
 
                         r = strv_consume(x, n);
                         if (r < 0)
-                                return r;
+                                goto fail;
 
                         previous_id = name->owner_id;
                 }
@@ -281,16 +283,18 @@
 
                 if (entry_name && service_name_is_valid(entry_name)) {
                         r = strv_extend(x, entry_name);
-                        if (r < 0)
-                                return -ENOMEM;
+                        if (r < 0) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
                 }
         }
 
-        r = kernel_cmd_free(bus, cmd.offset);
-        if (r < 0)
-                return r;
+        r = 0;
 
-        return 0;
+fail:
+        kernel_cmd_free(bus, cmd.offset);
+        return r;
 }
 
 static int bus_list_names_kernel(sd_bus *bus, char ***acquired, char ***activatable) {
@@ -388,61 +392,16 @@
                 return bus_list_names_dbus1(bus, acquired, activatable);
 }
 
-static int bus_get_owner_kdbus(
-                sd_bus *bus,
-                const char *name,
-                uint64_t mask,
-                sd_bus_creds **creds) {
+static int bus_populate_creds_from_items(sd_bus *bus,
+                                         struct kdbus_info *info,
+                                         uint64_t mask,
+                                         sd_bus_creds *c) {
 
-        _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
-        struct kdbus_cmd_conn_info *cmd;
-        struct kdbus_conn_info *conn_info;
         struct kdbus_item *item;
-        size_t size, l;
-        uint64_t m, id;
+        uint64_t m;
         int r;
 
-        r = bus_kernel_parse_unique_name(name, &id);
-        if (r < 0)
-                return r;
-        if (r > 0) {
-                size = offsetof(struct kdbus_cmd_conn_info, items);
-                cmd = alloca0_align(size, 8);
-                cmd->id = id;
-        } else {
-                l = strlen(name) + 1;
-                size = offsetof(struct kdbus_cmd_conn_info, items) + KDBUS_ITEM_SIZE(l);
-                cmd = alloca0_align(size, 8);
-                cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + l;
-                cmd->items[0].type = KDBUS_ITEM_NAME;
-                memcpy(cmd->items[0].str, name, l);
-        }
-
-        cmd->size = size;
-        kdbus_translate_attach_flags(mask, (uint64_t*) &cmd->flags);
-
-        r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd);
-        if (r < 0)
-                return -errno;
-
-        conn_info = (struct kdbus_conn_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
-
-        /* Non-activated names are considered not available */
-        if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
-                return name[0] == ':' ? -ENXIO : -ESRCH;
-
-        c = bus_creds_new();
-        if (!c)
-                return -ENOMEM;
-
-        if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
-                if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) conn_info->id) < 0)
-                        return -ENOMEM;
-
-                c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
-        }
-
-        KDBUS_ITEM_FOREACH(item, conn_info, items) {
+        KDBUS_ITEM_FOREACH(item, info, items) {
 
                 switch (item->type) {
 
@@ -471,10 +430,8 @@
                 case KDBUS_ITEM_PID_COMM:
                         if (mask & SD_BUS_CREDS_COMM) {
                                 c->comm = strdup(item->str);
-                                if (!c->comm) {
-                                        r = -ENOMEM;
-                                        goto fail;
-                                }
+                                if (!c->comm)
+                                        return -ENOMEM;
 
                                 c->mask |= SD_BUS_CREDS_COMM;
                         }
@@ -483,10 +440,8 @@
                 case KDBUS_ITEM_TID_COMM:
                         if (mask & SD_BUS_CREDS_TID_COMM) {
                                 c->tid_comm = strdup(item->str);
-                                if (!c->tid_comm) {
-                                        r = -ENOMEM;
-                                        goto fail;
-                                }
+                                if (!c->tid_comm)
+                                        return -ENOMEM;
 
                                 c->mask |= SD_BUS_CREDS_TID_COMM;
                         }
@@ -495,10 +450,8 @@
                 case KDBUS_ITEM_EXE:
                         if (mask & SD_BUS_CREDS_EXE) {
                                 c->exe = strdup(item->str);
-                                if (!c->exe) {
-                                        r = -ENOMEM;
-                                        goto fail;
-                                }
+                                if (!c->exe)
+                                        return -ENOMEM;
 
                                 c->mask |= SD_BUS_CREDS_EXE;
                         }
@@ -508,10 +461,8 @@
                         if (mask & SD_BUS_CREDS_CMDLINE) {
                                 c->cmdline_size = item->size - KDBUS_ITEM_HEADER_SIZE;
                                 c->cmdline = memdup(item->data, c->cmdline_size);
-                                if (!c->cmdline) {
-                                        r = -ENOMEM;
-                                        goto fail;
-                                }
+                                if (!c->cmdline)
+                                        return -ENOMEM;
 
                                 c->mask |= SD_BUS_CREDS_CMDLINE;
                         }
@@ -524,20 +475,16 @@
 
                         if (m) {
                                 c->cgroup = strdup(item->str);
-                                if (!c->cgroup) {
-                                        r = -ENOMEM;
-                                        goto fail;
-                                }
+                                if (!c->cgroup)
+                                        return -ENOMEM;
 
                                 r = bus_get_root_path(bus);
                                 if (r < 0)
-                                        goto fail;
+                                        return r;
 
                                 c->cgroup_root = strdup(bus->cgroup_root);
-                                if (!c->cgroup_root) {
-                                        r = -ENOMEM;
-                                        goto fail;
-                                }
+                                if (!c->cgroup_root)
+                                        return -ENOMEM;
 
                                 c->mask |= m;
                         }
@@ -548,12 +495,10 @@
                              SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
 
                         if (m) {
-                                c->capability_size = item->size - KDBUS_ITEM_HEADER_SIZE;
-                                c->capability = memdup(item->data, c->capability_size);
-                                if (!c->capability) {
-                                        r = -ENOMEM;
-                                        goto fail;
-                                }
+                                c->capability_size = item->size - offsetof(struct kdbus_item, caps.caps);
+                                c->capability = memdup(item->caps.caps, c->capability_size);
+                                if (!c->capability)
+                                        return -ENOMEM;
 
                                 c->mask |= m;
                         }
@@ -562,10 +507,8 @@
                 case KDBUS_ITEM_SECLABEL:
                         if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
                                 c->label = strdup(item->str);
-                                if (!c->label) {
-                                        r = -ENOMEM;
-                                        goto fail;
-                                }
+                                if (!c->label)
+                                        return -ENOMEM;
 
                                 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
                         }
@@ -585,7 +528,7 @@
                         if ((mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) && service_name_is_valid(item->name.name)) {
                                 r = strv_extend(&c->well_known_names, item->name.name);
                                 if (r < 0)
-                                        goto fail;
+                                        return r;
 
                                 c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
                         }
@@ -594,10 +537,8 @@
                 case KDBUS_ITEM_CONN_NAME:
                         if ((mask & SD_BUS_CREDS_CONNECTION_NAME)) {
                                 c->conn_name = strdup(item->str);
-                                if (!c->conn_name) {
-                                        r = -ENOMEM;
-                                        goto fail;
-                                }
+                                if (!c->conn_name)
+                                        return -ENOMEM;
 
                                 c->mask |= SD_BUS_CREDS_CONNECTION_NAME;
                         }
@@ -605,6 +546,75 @@
                 }
         }
 
+        return 0;
+}
+
+static int bus_get_name_creds_kdbus(
+                sd_bus *bus,
+                const char *name,
+                uint64_t mask,
+                sd_bus_creds **creds) {
+
+        _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
+        struct kdbus_cmd_info *cmd;
+        struct kdbus_info *conn_info;
+        size_t size, l;
+        uint64_t id;
+        int r;
+
+        r = bus_kernel_parse_unique_name(name, &id);
+        if (r < 0)
+                return r;
+        if (r > 0) {
+                size = offsetof(struct kdbus_cmd_info, items);
+                cmd = alloca0_align(size, 8);
+                cmd->id = id;
+        } else {
+                l = strlen(name) + 1;
+                size = offsetof(struct kdbus_cmd_info, items) + KDBUS_ITEM_SIZE(l);
+                cmd = alloca0_align(size, 8);
+                cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + l;
+                cmd->items[0].type = KDBUS_ITEM_NAME;
+                memcpy(cmd->items[0].str, name, l);
+        }
+
+        cmd->size = size;
+        kdbus_translate_attach_flags(mask, (uint64_t*) &cmd->flags);
+
+        r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd);
+        if (r < 0)
+                return -errno;
+
+        conn_info = (struct kdbus_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
+
+        /* Non-activated names are considered not available */
+        if (conn_info->flags & KDBUS_HELLO_ACTIVATOR) {
+                if (name[0] == ':')
+                        r = -ENXIO;
+                else
+                        r = -ESRCH;
+                goto fail;
+        }
+
+        c = bus_creds_new();
+        if (!c) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
+                if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) conn_info->id) < 0) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
+        }
+
+        r = bus_populate_creds_from_items(bus, conn_info, mask, c);
+        if (r < 0)
+                goto fail;
+
         if (creds) {
                 *creds = c;
                 c = NULL;
@@ -617,7 +627,7 @@
         return r;
 }
 
-static int bus_get_owner_dbus1(
+static int bus_get_name_creds_dbus1(
                 sd_bus *bus,
                 const char *name,
                 uint64_t mask,
@@ -763,7 +773,7 @@
         return 0;
 }
 
-_public_ int sd_bus_get_owner(
+_public_ int sd_bus_get_name_creds(
                 sd_bus *bus,
                 const char *name,
                 uint64_t mask,
@@ -781,9 +791,72 @@
                 return -ENOTCONN;
 
         if (bus->is_kernel)
-                return bus_get_owner_kdbus(bus, name, mask, creds);
+                return bus_get_name_creds_kdbus(bus, name, mask, creds);
         else
-                return bus_get_owner_dbus1(bus, name, mask, creds);
+                return bus_get_name_creds_dbus1(bus, name, mask, creds);
+}
+
+_public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
+        _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
+        pid_t pid = 0;
+        int r;
+
+        assert_return(bus, -EINVAL);
+        assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
+        assert_return(ret, -EINVAL);
+        assert_return(!bus_pid_changed(bus), -ECHILD);
+
+        if (!BUS_IS_OPEN(bus->state))
+                return -ENOTCONN;
+
+        if (!bus->ucred_valid && !isempty(bus->label))
+                return -ENODATA;
+
+        c = bus_creds_new();
+        if (!c)
+                return -ENOMEM;
+
+        if (bus->ucred_valid) {
+                pid = c->pid = bus->ucred.pid;
+                c->uid = bus->ucred.uid;
+                c->gid = bus->ucred.gid;
+
+                c->mask |= (SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID) & mask;
+        }
+
+        if (!isempty(bus->label) && (mask & SD_BUS_CREDS_SELINUX_CONTEXT)) {
+                c->label = strdup(bus->label);
+                if (!c->label)
+                        return -ENOMEM;
+
+                c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+        }
+
+        if (bus->is_kernel) {
+                struct kdbus_cmd_info cmd = {};
+                struct kdbus_info *creator_info;
+
+                cmd.size = sizeof(cmd);
+                r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd);
+                if (r < 0)
+                        return -errno;
+
+                creator_info = (struct kdbus_info *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
+
+                r = bus_populate_creds_from_items(bus, creator_info, mask, c);
+                kernel_cmd_free(bus, cmd.offset);
+
+                if (r < 0)
+                        return r;
+        } else {
+                r = bus_creds_add_more(c, mask, pid, 0);
+                if (r < 0)
+                        return r;
+        }
+
+        *ret = c;
+        c = NULL;
+        return 0;
 }
 
 static int add_name_change_match(sd_bus *bus,
@@ -1235,7 +1308,7 @@
                 return bus_remove_match_internal_dbus1(bus, match);
 }
 
-_public_ int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
+_public_ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
         const char *mid;
         int r;
diff -urN systemd-216/src/libsystemd/sd-bus/bus-convenience.c systemd-217/src/libsystemd/sd-bus/bus-convenience.c
--- systemd-216/src/libsystemd/sd-bus/bus-convenience.c	2014-08-15 10:56:07.086645207 -0700
+++ systemd-217/src/libsystemd/sd-bus/bus-convenience.c	2014-10-22 11:30:06.646837633 -0700
@@ -465,9 +465,9 @@
                  * to get it from the sender or peer */
 
                 if (call->sender)
-                        return sd_bus_get_owner(call->bus, call->sender, mask, creds);
+                        return sd_bus_get_name_creds(call->bus, call->sender, mask, creds);
                 else
-                        return sd_bus_get_peer_creds(call->bus, mask, creds);
+                        return sd_bus_get_owner_creds(call->bus, mask, creds);
         }
 
         return bus_creds_extend_by_pid(c, mask, creds);
diff -urN systemd-216/src/libsystemd/sd-bus/busctl.c systemd-217/src/libsystemd/sd-bus/busctl.c
--- systemd-216/src/libsystemd/sd-bus/busctl.c	2014-11-03 09:35:27.865175864 -0800
+++ systemd-217/src/libsystemd/sd-bus/busctl.c	2014-10-22 11:30:06.646837633 -0700
@@ -142,7 +142,7 @@
 
                 printf("%-*s", (int) max_i, *i);
 
-                r = sd_bus_get_owner(bus, *i,
+                r = sd_bus_get_name_creds(bus, *i,
                                      SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|
                                      SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_SESSION|
                                      SD_BUS_CREDS_CONNECTION_NAME, &creds);
@@ -210,7 +210,7 @@
                         printf("          - -               -                -             -                         -          -                  ");
 
                 if (arg_show_machine) {
-                        r = sd_bus_get_owner_machine_id(bus, *i, &mid);
+                        r = sd_bus_get_name_machine_id(bus, *i, &mid);
                         if (r >= 0) {
                                 char m[SD_ID128_STRING_MAX];
                                 printf(" %s\n", sd_id128_to_string(mid, m));
@@ -306,7 +306,7 @@
 
         r = parse_pid(argv[1], &pid);
         if (r < 0)
-                r = sd_bus_get_owner(bus, argv[1], _SD_BUS_CREDS_ALL, &creds);
+                r = sd_bus_get_name_creds(bus, argv[1], _SD_BUS_CREDS_ALL, &creds);
         else
                 r = sd_bus_creds_new_from_pid(&creds, pid, _SD_BUS_CREDS_ALL);
 
diff -urN systemd-216/src/libsystemd/sd-bus/bus-error.c systemd-217/src/libsystemd/sd-bus/bus-error.c
--- systemd-216/src/libsystemd/sd-bus/bus-error.c	2014-11-03 09:35:35.669254553 -0800
+++ systemd-217/src/libsystemd/sd-bus/bus-error.c	2014-10-24 10:24:19.999505311 -0700
@@ -194,13 +194,10 @@
                 return -ENOMEM;
         }
 
-        if (format) {
-                int r;
-
-                r = vasprintf((char**) &e->message, format, ap);
-                if (r < 0)
-                        return -ENOMEM;
-        }
+        /* Of we hit OOM on formatting the pretty message, we ignore
+         * this, since we at least managed to write the error name */
+        if (format)
+                (void) vasprintf((char**) &e->message, format, ap);
 
         e->_need_free = 1;
 
diff -urN systemd-216/src/libsystemd/sd-bus/bus-error-mapping.gperf systemd-217/src/libsystemd/sd-bus/bus-error-mapping.gperf
--- systemd-216/src/libsystemd/sd-bus/bus-error-mapping.gperf	2014-01-21 12:42:49.228055640 -0800
+++ systemd-217/src/libsystemd/sd-bus/bus-error-mapping.gperf	2014-10-28 06:57:25.403036410 -0700
@@ -13,37 +13,38 @@
 %struct-type
 %includes
 %%
-org.freedesktop.DBus.Error.Failed,                        EACCES
-org.freedesktop.DBus.Error.NoMemory,                      ENOMEM
-org.freedesktop.DBus.Error.ServiceUnknown,                EHOSTUNREACH
-org.freedesktop.DBus.Error.NameHasNoOwner,                ENXIO
-org.freedesktop.DBus.Error.NoReply,                       ETIMEDOUT
-org.freedesktop.DBus.Error.IOError,                       EIO
-org.freedesktop.DBus.Error.BadAddress,                    EADDRNOTAVAIL
-org.freedesktop.DBus.Error.NotSupported,                  ENOTSUP
-org.freedesktop.DBus.Error.LimitsExceeded,                ENOBUFS
-org.freedesktop.DBus.Error.AccessDenied,                  EACCES
-org.freedesktop.DBus.Error.AuthFailed,                    EACCES
-org.freedesktop.DBus.Error.NoServer,                      EHOSTDOWN
-org.freedesktop.DBus.Error.Timeout,                       ETIMEDOUT
-org.freedesktop.DBus.Error.NoNetwork,                     ENONET
-org.freedesktop.DBus.Error.AddressInUse,                  EADDRINUSE
-org.freedesktop.DBus.Error.Disconnected,                  ECONNRESET
-org.freedesktop.DBus.Error.InvalidArgs,                   EINVAL
-org.freedesktop.DBus.Error.FileNotFound,                  ENOENT
-org.freedesktop.DBus.Error.FileExists,                    EEXIST
-org.freedesktop.DBus.Error.UnknownMethod,                 EBADR
-org.freedesktop.DBus.Error.UnknownObject,                 EBADR
-org.freedesktop.DBus.Error.UnknownInterface,              EBADR
-org.freedesktop.DBus.Error.UnknownProperty,               EBADR
-org.freedesktop.DBus.Error.PropertyReadOnly,              EROFS
-org.freedesktop.DBus.Error.UnixProcessIdUnknown,          ESRCH
-org.freedesktop.DBus.Error.InvalidSignature,              EINVAL
-org.freedesktop.DBus.Error.InconsistentMessage,           EBADMSG
+org.freedesktop.DBus.Error.Failed,                          EACCES
+org.freedesktop.DBus.Error.NoMemory,                        ENOMEM
+org.freedesktop.DBus.Error.ServiceUnknown,                  EHOSTUNREACH
+org.freedesktop.DBus.Error.NameHasNoOwner,                  ENXIO
+org.freedesktop.DBus.Error.NoReply,                         ETIMEDOUT
+org.freedesktop.DBus.Error.IOError,                         EIO
+org.freedesktop.DBus.Error.BadAddress,                      EADDRNOTAVAIL
+org.freedesktop.DBus.Error.NotSupported,                    ENOTSUP
+org.freedesktop.DBus.Error.LimitsExceeded,                  ENOBUFS
+org.freedesktop.DBus.Error.AccessDenied,                    EACCES
+org.freedesktop.DBus.Error.AuthFailed,                      EACCES
+org.freedesktop.DBus.Error.InteractiveAuthorizationRequired EACCES
+org.freedesktop.DBus.Error.NoServer,                        EHOSTDOWN
+org.freedesktop.DBus.Error.Timeout,                         ETIMEDOUT
+org.freedesktop.DBus.Error.NoNetwork,                       ENONET
+org.freedesktop.DBus.Error.AddressInUse,                    EADDRINUSE
+org.freedesktop.DBus.Error.Disconnected,                    ECONNRESET
+org.freedesktop.DBus.Error.InvalidArgs,                     EINVAL
+org.freedesktop.DBus.Error.FileNotFound,                    ENOENT
+org.freedesktop.DBus.Error.FileExists,                      EEXIST
+org.freedesktop.DBus.Error.UnknownMethod,                   EBADR
+org.freedesktop.DBus.Error.UnknownObject,                   EBADR
+org.freedesktop.DBus.Error.UnknownInterface,                EBADR
+org.freedesktop.DBus.Error.UnknownProperty,                 EBADR
+org.freedesktop.DBus.Error.PropertyReadOnly,                EROFS
+org.freedesktop.DBus.Error.UnixProcessIdUnknown,            ESRCH
+org.freedesktop.DBus.Error.InvalidSignature,                EINVAL
+org.freedesktop.DBus.Error.InconsistentMessage,             EBADMSG
 #
-org.freedesktop.DBus.Error.TimedOut,                      ETIMEDOUT
-org.freedesktop.DBus.Error.MatchRuleInvalid,              EINVAL
-org.freedesktop.DBus.Error.InvalidFileContent,            EINVAL
-org.freedesktop.DBus.Error.MatchRuleNotFound,             ENOENT
-org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown, ESRCH
-org.freedesktop.DBus.Error.ObjectPathInUse,               EBUSY
+org.freedesktop.DBus.Error.TimedOut,                        ETIMEDOUT
+org.freedesktop.DBus.Error.MatchRuleInvalid,                EINVAL
+org.freedesktop.DBus.Error.InvalidFileContent,              EINVAL
+org.freedesktop.DBus.Error.MatchRuleNotFound,               ENOENT
+org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown,   ESRCH
+org.freedesktop.DBus.Error.ObjectPathInUse,                 EBUSY
diff -urN systemd-216/src/libsystemd/sd-bus/bus-internal.h systemd-217/src/libsystemd/sd-bus/bus-internal.h
--- systemd-216/src/libsystemd/sd-bus/bus-internal.h	2014-08-18 12:01:57.391667772 -0700
+++ systemd-217/src/libsystemd/sd-bus/bus-internal.h	2014-10-23 10:00:37.304180671 -0700
@@ -230,7 +230,7 @@
 
         struct bus_match_node match_callbacks;
         Prioq *reply_callbacks_prioq;
-        Hashmap *reply_callbacks;
+        OrderedHashmap *reply_callbacks;
         LIST_HEAD(struct filter_callback, filter_callbacks);
 
         Hashmap *nodes;
diff -urN systemd-216/src/libsystemd/sd-bus/bus-kernel.c systemd-217/src/libsystemd/sd-bus/bus-kernel.c
--- systemd-216/src/libsystemd/sd-bus/bus-kernel.c	2014-11-03 09:35:36.126259161 -0800
+++ systemd-217/src/libsystemd/sd-bus/bus-kernel.c	2014-10-27 10:09:26.606862015 -0700
@@ -270,10 +270,15 @@
         m->kdbus->cookie = (uint64_t) m->header->serial;
         m->kdbus->priority = m->priority;
 
-        if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
+        if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) {
                 m->kdbus->cookie_reply = m->reply_cookie;
-        else
-                m->kdbus->timeout_ns = m->timeout * NSEC_PER_USEC;
+        } else {
+                struct timespec now;
+
+                assert_se(clock_gettime(CLOCK_MONOTONIC_COARSE, &now) == 0);
+                m->kdbus->timeout_ns = now.tv_sec * NSEC_PER_SEC + now.tv_nsec +
+                                       m->timeout * NSEC_PER_USEC;
+        }
 
         d = m->kdbus->items;
 
@@ -570,8 +575,8 @@
                         break;
 
                 case KDBUS_ITEM_CAPS:
-                        m->creds.capability = d->data;
-                        m->creds.capability_size = l;
+                        m->creds.capability = (uint8_t *) d->caps.caps;
+                        m->creds.capability_size = d->size - offsetof(struct kdbus_item, caps.caps);
                         m->creds.mask |= (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS) & bus->creds_mask;
                         break;
 
@@ -714,7 +719,7 @@
 
         hello = alloca0_align(sz, 8);
         hello->size = sz;
-        hello->conn_flags = b->hello_flags;
+        hello->flags = b->hello_flags;
         hello->attach_flags = b->attach_flags;
         hello->pool_size = KDBUS_POOL_SIZE;
 
@@ -751,10 +756,9 @@
                 }
         }
 
-        /* The higher 32bit of both flags fields are considered
+        /* The higher 32bit of the bus_flags fields are considered
          * 'incompatible flags'. Refuse them all for now. */
-        if (hello->bus_flags > 0xFFFFFFFFULL ||
-            hello->conn_flags > 0xFFFFFFFFULL)
+        if (hello->bus_flags > 0xFFFFFFFFULL)
                 return -ENOTSUP;
 
         if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
@@ -770,7 +774,7 @@
 
         b->is_kernel = true;
         b->bus_client = true;
-        b->can_fds = !!(hello->conn_flags & KDBUS_HELLO_ACCEPT_FD);
+        b->can_fds = !!(hello->flags & KDBUS_HELLO_ACCEPT_FD);
         b->message_version = 2;
         b->message_endian = BUS_NATIVE_ENDIAN;
 
@@ -1230,8 +1234,11 @@
         if (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID))
                 m |= KDBUS_ATTACH_CREDS;
 
-        if (mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
-                m |= KDBUS_ATTACH_COMM;
+        if (mask & SD_BUS_CREDS_COMM)
+                m |= KDBUS_ATTACH_PID_COMM;
+
+        if (mask & SD_BUS_CREDS_TID_COMM)
+                m |= KDBUS_ATTACH_TID_COMM;
 
         if (mask & SD_BUS_CREDS_EXE)
                 m |= KDBUS_ATTACH_EXE;
@@ -1307,13 +1314,6 @@
                 return -errno;
         }
 
-        /* The features field are considered 'incompatible flags'.
-         * Refuse them all for now. */
-        if (make->features) {
-                safe_close(fd);
-                return -ENOTSUP;
-        }
-
         if (s) {
                 char *p;
 
@@ -1444,13 +1444,6 @@
                 return -errno;
         }
 
-        /* The features field are considered 'incompatible flags'.
-         * Refuse them all for now. */
-        if (make->features) {
-                safe_close(fd);
-                return -ENOTSUP;
-        }
-
         if (ep_path) {
                 char *p;
 
@@ -1565,7 +1558,7 @@
         }
 
         hello->size = size;
-        hello->conn_flags =
+        hello->flags =
                 (activating ? KDBUS_HELLO_ACTIVATOR : KDBUS_HELLO_POLICY_HOLDER) |
                 (accept_fd ? KDBUS_HELLO_ACCEPT_FD : 0);
         hello->pool_size = KDBUS_POOL_SIZE;
@@ -1574,11 +1567,9 @@
         if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0)
                 return -errno;
 
-        /* The higher 32bit of both flags fields are considered
+        /* The higher 32bit of the bus_flags fields are considered
          * 'incompatible flags'. Refuse them all for now. */
-        if (hello->features ||
-            hello->bus_flags > 0xFFFFFFFFULL ||
-            hello->conn_flags > 0xFFFFFFFFULL)
+        if (hello->bus_flags > 0xFFFFFFFFULL)
                 return -ENOTSUP;
 
         if (!bloom_validate_parameters((size_t) hello->bloom.size, (unsigned) hello->bloom.n_hash))
diff -urN systemd-216/src/libsystemd/sd-bus/bus-match.c systemd-217/src/libsystemd/sd-bus/bus-match.c
--- systemd-216/src/libsystemd/sd-bus/bus-match.c	2014-11-03 09:35:27.863175844 -0800
+++ systemd-217/src/libsystemd/sd-bus/bus-match.c	2014-11-03 09:33:48.562174593 -0800
@@ -537,7 +537,7 @@
         else if (BUS_MATCH_CAN_HASH(t))
                 n = hashmap_get(c->compare.children, value_str);
         else {
-                for (n = c->child; !value_node_same(n, t, value_u8, value_str); n = n->next)
+                for (n = c->child; n && !value_node_same(n, t, value_u8, value_str); n = n->next)
                         ;
         }
 
diff -urN systemd-216/src/libsystemd/sd-bus/bus-message.c systemd-217/src/libsystemd/sd-bus/bus-message.c
--- systemd-216/src/libsystemd/sd-bus/bus-message.c	2014-11-03 09:35:35.640254261 -0800
+++ systemd-217/src/libsystemd/sd-bus/bus-message.c	2014-10-13 08:19:31.341674513 -0700
@@ -849,6 +849,13 @@
         return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
 }
 
+_public_ int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m) {
+        assert_return(m, -EINVAL);
+
+        return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
+                (m->header->flags & BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION);
+}
+
 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
         assert_return(m, NULL);
 
@@ -998,6 +1005,18 @@
 
         return 0;
 }
+
+_public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b) {
+        assert_return(m, -EINVAL);
+        assert_return(!m->sealed, -EPERM);
+
+        if (b)
+                m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
+        else
+                m->header->flags &= ~BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
+
+        return 0;
+}
 
 static struct bus_container *message_get_container(sd_bus_message *m) {
         assert(m);
diff -urN systemd-216/src/libsystemd/sd-bus/bus-protocol.h systemd-217/src/libsystemd/sd-bus/bus-protocol.h
--- systemd-216/src/libsystemd/sd-bus/bus-protocol.h	2014-07-11 07:13:05.274563727 -0700
+++ systemd-217/src/libsystemd/sd-bus/bus-protocol.h	2014-10-13 08:19:31.341674513 -0700
@@ -42,7 +42,8 @@
 
 enum {
         BUS_MESSAGE_NO_REPLY_EXPECTED = 1,
-        BUS_MESSAGE_NO_AUTO_START = 2
+        BUS_MESSAGE_NO_AUTO_START = 2,
+        BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION = 4,
 };
 
 /* Header fields */
diff -urN systemd-216/src/libsystemd/sd-bus/bus-slot.c systemd-217/src/libsystemd/sd-bus/bus-slot.c
--- systemd-216/src/libsystemd/sd-bus/bus-slot.c	2014-08-18 09:11:26.888137004 -0700
+++ systemd-217/src/libsystemd/sd-bus/bus-slot.c	2014-10-23 10:00:37.304180671 -0700
@@ -75,7 +75,7 @@
         case BUS_REPLY_CALLBACK:
 
                 if (slot->reply_callback.cookie != 0)
-                        hashmap_remove(slot->bus->reply_callbacks, &slot->reply_callback.cookie);
+                        ordered_hashmap_remove(slot->bus->reply_callbacks, &slot->reply_callback.cookie);
 
                 if (slot->reply_callback.timeout != 0)
                         prioq_remove(slot->bus->reply_callbacks_prioq, &slot->reply_callback, &slot->reply_callback.prioq_idx);
diff -urN systemd-216/src/libsystemd/sd-bus/bus-track.c systemd-217/src/libsystemd/sd-bus/bus-track.c
--- systemd-216/src/libsystemd/sd-bus/bus-track.c	2014-11-03 09:35:28.065177881 -0800
+++ systemd-217/src/libsystemd/sd-bus/bus-track.c	2014-10-22 11:30:06.646837633 -0700
@@ -188,7 +188,7 @@
 
         /* Second, check if it is currently existing, or maybe
          * doesn't, or maybe disappeared already. */
-        r = sd_bus_get_owner(track->bus, n, 0, NULL);
+        r = sd_bus_get_name_creds(track->bus, n, 0, NULL);
         if (r < 0) {
                 hashmap_remove(track->names, n);
                 return r;
diff -urN systemd-216/src/libsystemd/sd-bus/bus-util.c systemd-217/src/libsystemd/sd-bus/bus-util.c
--- systemd-216/src/libsystemd/sd-bus/bus-util.c	2014-11-03 09:35:29.298190314 -0800
+++ systemd-217/src/libsystemd/sd-bus/bus-util.c	2014-10-28 07:11:23.956524425 -0700
@@ -212,13 +212,19 @@
 #ifdef ENABLE_POLKIT
         else {
                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
-                int authorized = false, challenge = false;
+                int authorized = false, challenge = false, c;
                 const char *sender;
 
                 sender = sd_bus_message_get_sender(call);
                 if (!sender)
                         return -EBADMSG;
 
+                c = sd_bus_message_get_allow_interactive_authorization(call);
+                if (c < 0)
+                        return c;
+                if (c > 0)
+                        interactive = true;
+
                 r = sd_bus_call_method(
                                 call->bus,
                                 "org.freedesktop.PolicyKit1",
@@ -231,7 +237,7 @@
                                 "system-bus-name", 1, "name", "s", sender,
                                 action,
                                 0,
-                                interactive ? 1 : 0,
+                                !!interactive,
                                 "");
 
                 if (r < 0) {
@@ -334,6 +340,7 @@
         const char *sender;
         sd_bus_message_handler_t callback;
         void *userdata;
+        int c;
 #endif
         int r;
 
@@ -375,6 +382,9 @@
                 if (authorized)
                         return 1;
 
+                if (challenge)
+                        return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
+
                 return -EACCES;
         }
 #endif
@@ -399,6 +409,12 @@
         if (!sender)
                 return -EBADMSG;
 
+        c = sd_bus_message_get_allow_interactive_authorization(call);
+        if (c < 0)
+                return c;
+        if (c > 0)
+                interactive = true;
+
         r = hashmap_ensure_allocated(registry, NULL);
         if (r < 0)
                 return r;
@@ -419,7 +435,7 @@
                         "system-bus-name", 1, "name", "s", sender,
                         action,
                         0,
-                        interactive ? 1 : 0,
+                        !!interactive,
                         NULL);
         if (r < 0)
                 return r;
diff -urN systemd-216/src/libsystemd/sd-bus/kdbus.h systemd-217/src/libsystemd/sd-bus/kdbus.h
--- systemd-216/src/libsystemd/sd-bus/kdbus.h	2014-11-03 09:35:36.127259171 -0800
+++ systemd-217/src/libsystemd/sd-bus/kdbus.h	2014-10-27 10:09:26.606862015 -0700
@@ -1,18 +1,8 @@
 /*
- * Copyright (C) 2013-2014 Kay Sievers
- * Copyright (C) 2013-2014 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
- * Copyright (C) 2013-2014 Linux Foundation
- * Copyright (C) 2013-2014 Lennart Poettering
- * Copyright (C) 2013-2014 Daniel Mack <daniel@zonque.org>
- * Copyright (C) 2013-2014 David Herrmann <dh.herrmann@gmail.com>
- *
  * kdbus 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.
- *
- * "Everything should be made as simple as possible, but not simpler."
- *   -- Albert Einstein
  */
 
 #ifndef _KDBUS_UAPI_H_
@@ -26,6 +16,7 @@
 #define KDBUS_DST_ID_NAME		(0)
 #define KDBUS_MATCH_ID_ANY		(~0ULL)
 #define KDBUS_DST_ID_BROADCAST		(~0ULL)
+#define KDBUS_FLAG_KERNEL		(1ULL << 63)
 
 /**
  * struct kdbus_notify_id_change - name registry change message
@@ -89,6 +80,21 @@
 };
 
 /**
+ * struct kdbus_caps - process capabilities
+ * @last_cap:	Highest currently known capability bit
+ * @caps:	Variable number of 32-bit capabilities flags
+ *
+ * Contains a variable number of 32-bit capabilities flags.
+ *
+ * Attached to:
+ *   KDBUS_ITEM_CAPS
+ */
+struct kdbus_caps {
+	__u32 last_cap;
+	__u32 caps[0];
+};
+
+/**
  * struct kdbus_audit - audit information
  * @sessionid:		The audit session ID
  * @loginuid:		The audit login uid
@@ -321,6 +327,7 @@
 		struct kdbus_vec vec;
 		struct kdbus_creds creds;
 		struct kdbus_audit audit;
+		struct kdbus_caps caps;
 		struct kdbus_timestamp timestamp;
 		struct kdbus_name name;
 		struct kdbus_bloom_parameter bloom_parameter;
@@ -372,7 +379,8 @@
 /**
  * struct kdbus_msg - the representation of a kdbus message
  * @size:		Total size of the message
- * @flags:		Message flags (KDBUS_MSG_FLAGS_*)
+ * @flags:		Message flags (KDBUS_MSG_FLAGS_*), userspace → kernel
+ * @kernel_flags:	Supported message flags, kernel → userspace
  * @priority:		Message queue priority value
  * @dst_id:		64-bit ID of the destination connection
  * @src_id:		64-bit ID of the source connection
@@ -382,7 +390,8 @@
  * @timeout_ns:		The time to wait for a message reply from the peer.
  *			If there is no reply, a kernel-generated message
  *			with an attached KDBUS_ITEM_REPLY_TIMEOUT item
- *			is sent to @src_id.
+ *			is sent to @src_id. The timeout is expected in
+ *			nanoseconds and as absolute CLOCK_MONOTONIC value.
  * @cookie_reply:	A reply to the requesting message with the same
  *			cookie. The requesting connection can match its
  *			request and the reply with this value
@@ -394,6 +403,7 @@
 struct kdbus_msg {
 	__u64 size;
 	__u64 flags;
+	__u64 kernel_flags;
 	__s64 priority;
 	__u64 dst_id;
 	__u64 src_id;
@@ -428,7 +438,8 @@
 
 /**
  * struct kdbus_cmd_recv - struct to de-queue a buffered message
- * @flags:		KDBUS_RECV_* flags
+ * @flags:		KDBUS_RECV_* flags, userspace → kernel
+ * @kernel_flags:	Supported KDBUS_RECV_* flags, kernel → userspace
  * @priority:		Minimum priority of the messages to de-queue. Lowest
  *			values have the highest priority.
  * @offset:		Returned offset in the pool where the message is
@@ -439,6 +450,7 @@
  */
 struct kdbus_cmd_recv {
 	__u64 flags;
+	__u64 kernel_flags;
 	__s64 priority;
 	__u64 offset;
 } __attribute__((aligned(8)));
@@ -457,15 +469,17 @@
 
 /**
  * struct kdbus_cmd_free - struct to free a slice of memory in the pool
- * @offset		The offset of the memory slice, as returned by other
+ * @offset:		The offset of the memory slice, as returned by other
  *			ioctls
- * @flags		Flags for the free command. Currently unused.
+ * @flags:		Flags for the free command, userspace → kernel
+ * @kernel_flags:	Supported flags of the free command, userspace → kernel
  *
  * This struct is used with the KDBUS_CMD_FREE ioctl.
  */
 struct kdbus_cmd_free {
 	__u64 offset;
 	__u64 flags;
+	__u64 kernel_flags;
 } __attribute__((aligned(8)));
 
 /**
@@ -525,7 +539,8 @@
  * @KDBUS_ATTACH_CREDS:		Credentials
  * @KDBUS_ATTACH_AUXGROUPS:	Auxiliary groups
  * @KDBUS_ATTACH_NAMES:		Well-known names
- * @KDBUS_ATTACH_COMM:		The "comm" process identifier
+ * @KDBUS_ATTACH_COMM_TID:	The "comm" process identifier of the TID
+ * @KDBUS_ATTACH_COMM_PID:	The "comm" process identifier of the PID
  * @KDBUS_ATTACH_EXE:		The path of the executable
  * @KDBUS_ATTACH_CMDLINE:	The process command line
  * @KDBUS_ATTACH_CGROUP:	The croup membership
@@ -540,22 +555,23 @@
 	KDBUS_ATTACH_CREDS		=  1ULL <<  1,
 	KDBUS_ATTACH_AUXGROUPS		=  1ULL <<  2,
 	KDBUS_ATTACH_NAMES		=  1ULL <<  3,
-	KDBUS_ATTACH_COMM		=  1ULL <<  4,
-	KDBUS_ATTACH_EXE		=  1ULL <<  5,
-	KDBUS_ATTACH_CMDLINE		=  1ULL <<  6,
-	KDBUS_ATTACH_CGROUP		=  1ULL <<  7,
-	KDBUS_ATTACH_CAPS		=  1ULL <<  8,
-	KDBUS_ATTACH_SECLABEL		=  1ULL <<  9,
-	KDBUS_ATTACH_AUDIT		=  1ULL << 10,
-	KDBUS_ATTACH_CONN_NAME		=  1ULL << 11,
-	_KDBUS_ATTACH_ALL		=  (1ULL << 12) - 1,
+	KDBUS_ATTACH_TID_COMM		=  1ULL <<  4,
+	KDBUS_ATTACH_PID_COMM		=  1ULL <<  5,
+	KDBUS_ATTACH_EXE		=  1ULL <<  6,
+	KDBUS_ATTACH_CMDLINE		=  1ULL <<  7,
+	KDBUS_ATTACH_CGROUP		=  1ULL <<  8,
+	KDBUS_ATTACH_CAPS		=  1ULL <<  9,
+	KDBUS_ATTACH_SECLABEL		=  1ULL << 10,
+	KDBUS_ATTACH_AUDIT		=  1ULL << 11,
+	KDBUS_ATTACH_CONN_NAME		=  1ULL << 12,
+	_KDBUS_ATTACH_ALL		=  (1ULL << 13) - 1,
 };
 
 /**
  * struct kdbus_cmd_hello - struct to say hello to kdbus
  * @size:		The total size of the structure
- * @features:		Feature negotiation bitmask
- * @conn_flags:		Connection flags (KDBUS_HELLO_*).
+ * @flags:		Connection flags (KDBUS_HELLO_*), userspace → kernel
+ * @kernel_flags:	Supported connection flags, kernel → userspace
  * @attach_flags:	Mask of metadata to attach to each message sent
  *			(KDBUS_ATTACH_*)
  * @bus_flags:		The flags field copied verbatim from the original
@@ -574,8 +590,8 @@
  */
 struct kdbus_cmd_hello {
 	__u64 size;
-	__u64 features;
-	__u64 conn_flags;
+	__u64 flags;
+	__u64 kernel_flags;
 	__u64 attach_flags;
 	__u64 bus_flags;
 	__u64 id;
@@ -598,8 +614,9 @@
 /**
  * struct kdbus_cmd_make - struct to make a bus, an endpoint or a domain
  * @size:		The total size of the struct
- * @features:		Feature negotiation bitmask
- * @flags:		Properties for the bus/ep/domain to create
+ * @flags:		Properties for the bus/ep/domain to create,
+ *			userspace → kernel
+ * @kernel_flags:	Supported flags for the used command, kernel → userspace
  * @items:		Items describing details
  *
  * This structure is used with the KDBUS_CMD_BUS_MAKE, KDBUS_CMD_ENDPOINT_MAKE
@@ -607,8 +624,8 @@
  */
 struct kdbus_cmd_make {
 	__u64 size;
-	__u64 features;
 	__u64 flags;
+	__u64 kernel_flags;
 	struct kdbus_item items[0];
 } __attribute__((aligned(8)));
 
@@ -631,9 +648,9 @@
 /**
  * struct kdbus_cmd_name - struct to describe a well-known name
  * @size:		The total size of the struct
- * @flags:		Flags for a name entry (KDBUS_NAME_*)
- * @owner_id:		The current owner of the name
- * @conn_flags:		The flags of the owning connection (KDBUS_HELLO_*)
+ * @flags:		Flags for a name entry (KDBUS_NAME_*),
+ *			userspace → kernel, kernel → userspace
+ * @kernel_flags:	Supported flags for a name entry, kernel → userspace
  * @items:		Item list, containing the well-known name as
  *			KDBUS_ITEM_NAME
  *
@@ -642,8 +659,26 @@
 struct kdbus_cmd_name {
 	__u64 size;
 	__u64 flags;
-	__u64 owner_id;
+	__u64 kernel_flags;
+	struct kdbus_item items[0];
+} __attribute__((aligned(8)));
+
+/**
+ * struct kdbus_name_info - struct to describe a well-known name
+ * @size:		The total size of the struct
+ * @flags:		Flags for a name entry (KDBUS_NAME_*),
+ * @conn_flags:		The flags of the owning connection (KDBUS_HELLO_*)
+ * @owner_id:		The current owner of the name
+ * @items:		Item list, containing the well-known name as
+ *			KDBUS_ITEM_NAME
+ *
+ * This structure is used as return struct for the KDBUS_CMD_NAME_LIST ioctl.
+ */
+struct kdbus_name_info {
+	__u64 size;
+	__u64 flags;
 	__u64 conn_flags;
+	__u64 owner_id;
 	struct kdbus_item items[0];
 } __attribute__((aligned(8)));
 
@@ -663,7 +698,9 @@
 
 /**
  * struct kdbus_cmd_name_list - request a list of name entries
- * @flags:		Flags for the query (KDBUS_NAME_LIST_*)
+ * @flags:		Flags for the query (KDBUS_NAME_LIST_*),
+ * 			userspace → kernel
+ * @kernel_flags:	Supported flags for queries, kernel → userspace
  * @offset:		The returned offset in the caller's pool buffer.
  *			The user must use KDBUS_CMD_FREE to free the
  *			allocated memory.
@@ -672,6 +709,7 @@
  */
 struct kdbus_cmd_name_list {
 	__u64 flags;
+	__u64 kernel_flags;
 	__u64 offset;
 } __attribute__((aligned(8)));
 
@@ -685,45 +723,48 @@
  */
 struct kdbus_name_list {
 	__u64 size;
-	struct kdbus_cmd_name names[0];
+	struct kdbus_name_info names[0];
 };
 
 /**
- * struct kdbus_cmd_conn_info - struct used for KDBUS_CMD_CONN_INFO ioctl
+ * struct kdbus_cmd_info - struct used for KDBUS_CMD_CONN_INFO ioctl
  * @size:		The total size of the struct
- * @flags:		KDBUS_ATTACH_* flags
+ * @flags:		KDBUS_ATTACH_* flags, userspace → kernel
+ * @kernel_flags:	Supported KDBUS_ATTACH_* flags, kernel → userspace
  * @id:			The 64-bit ID of the connection. If set to zero, passing
  *			@name is required. kdbus will look up the name to
  *			determine the ID in this case.
  * @offset:		Returned offset in the caller's pool buffer where the
- *			kdbus_conn_info struct result is stored. The user must
+ *			kdbus_info struct result is stored. The user must
  *			use KDBUS_CMD_FREE to free the allocated memory.
- * @name:		The optional well-known name to look up. Only needed in
- *			case @id is zero.
+ * @items:		The optional item list, containing the
+ *			well-known name to look up as a KDBUS_ITEM_NAME.
+ *			Only needed in case @id is zero.
  *
  * On success, the KDBUS_CMD_CONN_INFO ioctl will return 0 and @offset will
  * tell the user the offset in the connection pool buffer at which to find the
- * result in a struct kdbus_conn_info.
+ * result in a struct kdbus_info.
  */
-struct kdbus_cmd_conn_info {
+struct kdbus_cmd_info {
 	__u64 size;
 	__u64 flags;
+	__u64 kernel_flags;
 	__u64 id;
 	__u64 offset;
 	struct kdbus_item items[0];
 } __attribute__((aligned(8)));
 
 /**
- * struct kdbus_conn_info - information returned by KDBUS_CMD_CONN_INFO
+ * struct kdbus_info - information returned by KDBUS_CMD_*_INFO
  * @size:		The total size of the struct
- * @id:			The connection's 64-bit ID
- * @flags:		The connection's flags
+ * @id:			The connection's or bus' 64-bit ID
+ * @flags:		The connection's or bus' flags
  * @items:		A list of struct kdbus_item
  *
  * Note that the user is responsible for freeing the allocated memory with
  * the KDBUS_CMD_FREE ioctl.
  */
-struct kdbus_conn_info {
+struct kdbus_info {
 	__u64 size;
 	__u64 id;
 	__u64 flags;
@@ -733,6 +774,8 @@
 /**
  * struct kdbus_cmd_update - update flags of a connection
  * @size:		The total size of the struct
+ * @flags:		Flags for the update command, userspace → kernel
+ * @kernel_flags:	Supported flags for this command, kernel → userspace
  * @items:		A list of struct kdbus_item
  *
  * This struct is used with the KDBUS_CMD_CONN_UPDATE ioctl.
@@ -740,6 +783,7 @@
 struct kdbus_cmd_update {
 	__u64 size;
 	__u64 flags;
+	__u64 kernel_flags;
 	struct kdbus_item items[0];
 } __attribute__((aligned(8)));
 
@@ -758,15 +802,19 @@
  * @size:		The total size of the struct
  * @cookie:		Userspace supplied cookie. When removing, the cookie
  *			identifies the match to remove
+ * @flags:		Flags for match command (KDBUS_MATCH_*),
+ *			userspace → kernel
+ * @kernel_flags:	Supported flags of the used command, kernel → userspace
  * @items:		A list of items for additional information
  *
- * This structure is used with the KDBUS_CMD_ADD_MATCH and
- * KDBUS_CMD_REMOVE_MATCH ioctl.
+ * This structure is used with the KDBUS_CMD_MATCH_ADD and
+ * KDBUS_CMD_MATCH_REMOVE ioctl.
  */
 struct kdbus_cmd_match {
 	__u64 size;
 	__u64 cookie;
 	__u64 flags;
+	__u64 kernel_flags;
 	struct kdbus_item items[0];
 } __attribute__((aligned(8)));
 
@@ -815,6 +863,8 @@
  * @KDBUS_CMD_CONN_UPDATE:	Update the properties of a connection. Used to
  *				update the metadata subscription mask and
  *				policy.
+ * @KDBUS_CMD_BUS_CREATOR_INFO:	Retrieve information of the creator of the bus
+ *				a connection is attached to.
  * @KDBUS_CMD_ENDPOINT_UPDATE:	Update the properties of a custom enpoint. Used
  *				to update the policy.
  * @KDBUS_CMD_MATCH_ADD:	Install a match which broadcast messages should
@@ -850,9 +900,11 @@
 					      struct kdbus_cmd_name_list),
 
 	KDBUS_CMD_CONN_INFO =		_IOWR(KDBUS_IOCTL_MAGIC, 0x60,
-					      struct kdbus_cmd_conn_info),
+					      struct kdbus_cmd_info),
 	KDBUS_CMD_CONN_UPDATE =		_IOW(KDBUS_IOCTL_MAGIC, 0x61,
 					     struct kdbus_cmd_update),
+	KDBUS_CMD_BUS_CREATOR_INFO =	_IOWR(KDBUS_IOCTL_MAGIC, 0x62,
+					      struct kdbus_cmd_info),
 
 	KDBUS_CMD_ENDPOINT_UPDATE =	_IOW(KDBUS_IOCTL_MAGIC, 0x71,
 					     struct kdbus_cmd_update),
diff -urN systemd-216/src/libsystemd/sd-bus/PORTING-DBUS1 systemd-217/src/libsystemd/sd-bus/PORTING-DBUS1
--- systemd-216/src/libsystemd/sd-bus/PORTING-DBUS1	2014-08-18 09:12:55.831023932 -0700
+++ systemd-217/src/libsystemd/sd-bus/PORTING-DBUS1	2014-10-07 06:59:01.462579986 -0700
@@ -66,7 +66,7 @@
 
 The kernel will return in the "id" field your unique id. This is a
 simple numeric value. For compatibility with classic dbus1 simply
-format this as string and prefix ":0.".
+format this as string and prefix ":1.".
 
 The kernel will also return the bloom filter size and bloom filter
 hash function number used for the signal broadcast bloom filter (see
@@ -156,11 +156,11 @@
    contained in the payload, as well is immediately before framing of a
    Gvariant, as well after as any padding bytes if there are any. The
    padding bytes must be wholly contained in the preceding
-   PAYLOAD_VEC/PAYLOAD_MEMFD item. You may not split up simple types
-   nor arrays of trivial types. The latter is necessary to allow APIs
-   to return direct pointers to linear chunks of fixed size trivial
-   arrays. Examples: The simple types "u", "s", "t" have to be in the
-   same payload item. The array of simple types "ay", "ai" have to be
+   PAYLOAD_VEC/PAYLOAD_MEMFD item. You may not split up basic types
+   nor arrays of fixed types. The latter is necessary to allow APIs
+   to return direct pointers to linear arrays of numeric
+   values. Examples: The basic types "u", "s", "t" have to be in the
+   same payload item. The array of fixed types "ay", "ai" have to be
    fully in contained in the same payload item. For an array "as" or
    "a(si)" the only restriction however is to keep each string
    individually in an uninterrupted item, to keep the framing of each
diff -urN systemd-216/src/libsystemd/sd-bus/sd-bus.c systemd-217/src/libsystemd/sd-bus/sd-bus.c
--- systemd-216/src/libsystemd/sd-bus/sd-bus.c	2014-11-03 09:35:36.416262085 -0800
+++ systemd-217/src/libsystemd/sd-bus/sd-bus.c	2014-10-27 05:05:35.697314393 -0700
@@ -139,7 +139,7 @@
 
         bus_reset_queues(b);
 
-        hashmap_free_free(b->reply_callbacks);
+        ordered_hashmap_free_free(b->reply_callbacks);
         prioq_free(b->reply_callbacks_prioq);
 
         assert(b->match_callbacks.type == BUS_MATCH_ROOT);
@@ -767,7 +767,7 @@
         if (!machine)
                 return -EINVAL;
 
-        if (!filename_is_safe(machine))
+        if (!machine_name_is_valid(machine))
                 return -EINVAL;
 
         free(b->machine);
@@ -809,7 +809,7 @@
         if (!machine)
                 return -EINVAL;
 
-        if (!filename_is_safe(machine))
+        if (!machine_name_is_valid(machine))
                 return -EINVAL;
 
         free(b->machine);
@@ -1157,17 +1157,13 @@
                         return -ENOMEM;
 
 #ifdef ENABLE_KDBUS
-                asprintf(&b->address, KERNEL_USER_BUS_FMT ";" UNIX_USER_BUS_FMT, getuid(), ee);
+                (void) asprintf(&b->address, KERNEL_USER_BUS_FMT ";" UNIX_USER_BUS_FMT, getuid(), ee);
 #else
-                asprintf(&b->address, UNIX_USER_BUS_FMT, ee);
+                (void) asprintf(&b->address, UNIX_USER_BUS_FMT, ee);
 #endif
         } else {
 #ifdef ENABLE_KDBUS
-                int r;
-
-                r = asprintf(&b->address, KERNEL_USER_BUS_FMT, getuid());
-                if (r < 0)
-                        return -ENOMEM;
+                (void) asprintf(&b->address, KERNEL_USER_BUS_FMT, getuid());
 #else
                 return -ECONNREFUSED;
 #endif
@@ -1309,7 +1305,7 @@
 
         assert_return(machine, -EINVAL);
         assert_return(ret, -EINVAL);
-        assert_return(filename_is_safe(machine), -EINVAL);
+        assert_return(machine_name_is_valid(machine), -EINVAL);
 
         r = sd_bus_new(&bus);
         if (r < 0)
@@ -1759,7 +1755,7 @@
         if (!BUS_IS_OPEN(bus->state))
                 return -ENOTCONN;
 
-        r = hashmap_ensure_allocated(&bus->reply_callbacks, &uint64_hash_ops);
+        r = ordered_hashmap_ensure_allocated(&bus->reply_callbacks, &uint64_hash_ops);
         if (r < 0)
                 return r;
 
@@ -1782,7 +1778,7 @@
         s->reply_callback.callback = callback;
 
         s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m);
-        r = hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback);
+        r = ordered_hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback);
         if (r < 0) {
                 s->reply_callback.cookie = 0;
                 return r;
@@ -2096,7 +2092,7 @@
         assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
         c->timeout = 0;
 
-        hashmap_remove(bus->reply_callbacks, &c->cookie);
+        ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
         c->cookie = 0;
 
         slot = container_of(c, sd_bus_slot, reply_callback);
@@ -2165,7 +2161,7 @@
         if (m->destination && bus->unique_name && !streq_ptr(m->destination, bus->unique_name))
                 return 0;
 
-        c = hashmap_remove(bus->reply_callbacks, &m->reply_cookie);
+        c = ordered_hashmap_remove(bus->reply_callbacks, &m->reply_cookie);
         if (!c)
                 return 0;
 
@@ -2499,7 +2495,7 @@
         assert(bus);
         assert(bus->state == BUS_CLOSING);
 
-        c = hashmap_first(bus->reply_callbacks);
+        c = ordered_hashmap_first(bus->reply_callbacks);
         if (c) {
                 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
                 sd_bus_slot *slot;
@@ -2522,7 +2518,7 @@
                         c->timeout = 0;
                 }
 
-                hashmap_remove(bus->reply_callbacks, &c->cookie);
+                ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
                 c->cookie = 0;
 
                 slot = container_of(c, sd_bus_slot, reply_callback);
@@ -3300,57 +3296,6 @@
         return 1;
 }
 
-_public_ int sd_bus_get_peer_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
-        sd_bus_creds *c;
-        pid_t pid = 0;
-        int r;
-
-        assert_return(bus, -EINVAL);
-        assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
-        assert_return(ret, -EINVAL);
-        assert_return(!bus_pid_changed(bus), -ECHILD);
-
-        if (bus->is_kernel)
-                return -ENOTSUP;
-
-        if (!BUS_IS_OPEN(bus->state))
-                return -ENOTCONN;
-
-        if (!bus->ucred_valid && !isempty(bus->label))
-                return -ENODATA;
-
-        c = bus_creds_new();
-        if (!c)
-                return -ENOMEM;
-
-        if (bus->ucred_valid) {
-                pid = c->pid = bus->ucred.pid;
-                c->uid = bus->ucred.uid;
-                c->gid = bus->ucred.gid;
-
-                c->mask |= (SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID) & mask;
-        }
-
-        if (!isempty(bus->label) && (mask & SD_BUS_CREDS_SELINUX_CONTEXT)) {
-                c->label = strdup(bus->label);
-                if (!c->label) {
-                        sd_bus_creds_unref(c);
-                        return -ENOMEM;
-                }
-
-                c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
-        }
-
-        r = bus_creds_add_more(c, mask, pid, 0);
-        if (r < 0) {
-                sd_bus_creds_unref(c);
-                return r;
-        }
-
-        *ret = c;
-        return 0;
-}
-
 _public_ int sd_bus_try_close(sd_bus *bus) {
         int r;
 
diff -urN systemd-216/src/libsystemd/sd-bus/test-bus-cleanup.c systemd-217/src/libsystemd/sd-bus/test-bus-cleanup.c
--- systemd-216/src/libsystemd/sd-bus/test-bus-cleanup.c	2014-03-18 10:05:51.365377795 -0700
+++ systemd-217/src/libsystemd/sd-bus/test-bus-cleanup.c	2014-10-13 08:19:31.023675584 -0700
@@ -34,11 +34,18 @@
         printf("after new: refcount %u\n", REFCNT_GET(bus->n_ref));
 }
 
-static void test_bus_open(void) {
+static int test_bus_open(void) {
         _cleanup_bus_unref_ sd_bus *bus = NULL;
+        int r;
 
-        assert_se(sd_bus_open_system(&bus) >= 0);
+        r = sd_bus_open_system(&bus);
+        if (r == -ECONNREFUSED || r == -ENOENT)
+                return r;
+
+        assert_se(r >= 0);
         printf("after open: refcount %u\n", REFCNT_GET(bus->n_ref));
+
+        return 0;
 }
 
 static void test_bus_new_method_call(void) {
@@ -70,11 +77,20 @@
 }
 
 int main(int argc, char **argv) {
+        int r;
+
         log_parse_environment();
         log_open();
 
         test_bus_new();
-        test_bus_open();
+        r = test_bus_open();
+        if (r < 0) {
+                log_info("Failed to connect to bus, skipping tests.");
+                return EXIT_TEST_SKIP;
+        }
+
         test_bus_new_method_call();
         test_bus_new_signal();
+
+        return EXIT_SUCCESS;
 }
diff -urN systemd-216/src/libsystemd/sd-daemon/sd-daemon.c systemd-217/src/libsystemd/sd-daemon/sd-daemon.c
--- systemd-216/src/libsystemd/sd-daemon/sd-daemon.c	2014-07-10 12:11:58.766294974 -0700
+++ systemd-217/src/libsystemd/sd-daemon/sd-daemon.c	2014-10-23 08:06:27.947110170 -0700
@@ -491,39 +491,35 @@
 }
 
 _public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) {
-        const char *e;
+        const char *s, *p = ""; /* p is set to dummy value to do unsetting */
         uint64_t u;
-        pid_t pid;
-        int r;
+        int r = 0;
 
-        e = getenv("WATCHDOG_PID");
-        if (!e) {
-                r = 0;
+        s = getenv("WATCHDOG_USEC");
+        if (!s)
                 goto finish;
-        }
 
-        r = parse_pid(e, &pid);
+        r = safe_atou64(s, &u);
         if (r < 0)
                 goto finish;
-
-        /* Is this for us? */
-        if (getpid() != pid) {
-                r = 0;
-                goto finish;
-        }
-
-        e = getenv("WATCHDOG_USEC");
-        if (!e) {
+        if (u <= 0) {
                 r = -EINVAL;
                 goto finish;
         }
 
-        r = safe_atou64(e, &u);
-        if (r < 0)
-                goto finish;
-        if (u <= 0) {
-                r = -EINVAL;
-                goto finish;
+        p = getenv("WATCHDOG_PID");
+        if (p) {
+                pid_t pid;
+
+                r = parse_pid(p, &pid);
+                if (r < 0)
+                        goto finish;
+
+                /* Is this for us? */
+                if (getpid() != pid) {
+                        r = 0;
+                        goto finish;
+                }
         }
 
         if (usec)
@@ -532,10 +528,10 @@
         r = 1;
 
 finish:
-        if (unset_environment) {
-                unsetenv("WATCHDOG_PID");
+        if (unset_environment && s)
                 unsetenv("WATCHDOG_USEC");
-        }
+        if (unset_environment && p)
+                unsetenv("WATCHDOG_PID");
 
         return r;
 }
diff -urN systemd-216/src/libsystemd-network/dhcp-internal.h systemd-217/src/libsystemd-network/dhcp-internal.h
--- systemd-216/src/libsystemd-network/dhcp-internal.h	2014-07-07 06:25:55.295467217 -0700
+++ systemd-217/src/libsystemd-network/dhcp-internal.h	2014-10-13 08:19:31.018675601 -0700
@@ -24,6 +24,7 @@
 
 #include <stdint.h>
 #include <linux/if_packet.h>
+#include <net/if_arp.h>
 #include <net/ethernet.h>
 
 #include "socket-util.h"
@@ -31,7 +32,9 @@
 #include "sd-dhcp-client.h"
 #include "dhcp-protocol.h"
 
-int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, uint32_t xid, struct ether_addr mac_addr);
+int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
+                                 uint32_t xid, const uint8_t *mac_addr,
+                                 size_t mac_addr_len, uint16_t arp_type);
 int dhcp_network_bind_udp_socket(be32_t address, uint16_t port);
 int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
                                  const void *packet, size_t len);
@@ -47,8 +50,9 @@
 int dhcp_option_parse(DHCPMessage *message, size_t len,
                       dhcp_option_cb_t cb, void *user_data);
 
-int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid, uint8_t type,
-                      size_t optlen, size_t *optoffset);
+int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
+                      uint8_t type, uint16_t arp_type, size_t optlen,
+                      size_t *optoffset);
 
 uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len);
 
diff -urN systemd-216/src/libsystemd-network/dhcp-network.c systemd-217/src/libsystemd-network/dhcp-network.c
--- systemd-216/src/libsystemd-network/dhcp-network.c	2014-07-29 14:53:08.067092201 -0700
+++ systemd-217/src/libsystemd-network/dhcp-network.c	2014-10-13 08:19:31.019675598 -0700
@@ -22,6 +22,7 @@
 #include <sys/socket.h>
 #include <string.h>
 #include <linux/if_packet.h>
+#include <linux/if_infiniband.h>
 #include <net/ethernet.h>
 #include <net/if_arp.h>
 #include <stdio.h>
@@ -32,9 +33,12 @@
 
 #include "dhcp-internal.h"
 
-int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
-                                 uint32_t xid, struct ether_addr mac_addr) {
-
+static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
+                            uint32_t xid, const uint8_t *mac_addr,
+                            size_t mac_addr_len,
+                            const uint8_t *bcast_addr,
+                            const struct ether_addr *eth_mac,
+                            uint16_t arp_type, uint8_t dhcp_hlen) {
         struct sock_filter filter[] = {
                 BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0),                                 /* A <- packet length */
                 BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 1, 0),         /* packet >= DHCPPacket ? */
@@ -57,21 +61,21 @@
                 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTREPLY, 1, 0),                  /* op == BOOTREPLY ? */
                 BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
                 BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.htype)),  /* A <- DHCP header type */
-                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPHRD_ETHER, 1, 0),               /* header type == ARPHRD_ETHER ? */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arp_type, 1, 0),                   /* header type == arp_type ? */
                 BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
                 BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, dhcp.hlen)),   /* A <- mac address length */
-                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHER_ADDR_LEN, 1, 0),             /* address length == ETHER_ADDR_LEN ? */
+                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, dhcp_hlen, 1, 0),                  /* address length == dhcp_hlen ? */
                 BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
                 BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.xid)),    /* A <- client identifier */
                 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0),                        /* client identifier == xid ? */
                 BPF_STMT(BPF_RET + BPF_K, 0),                                          /* ignore */
-                BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((unsigned int *) &mac_addr))),                    /* A <- 4 bytes of client's MAC */
+                BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((unsigned int *) eth_mac))),                     /* A <- 4 bytes of client's MAC */
                 BPF_STMT(BPF_MISC + BPF_TAX, 0),                                                       /* X <- A */
                 BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr)),                 /* A <- 4 bytes of MAC from dhcp.chaddr */
                 BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0),                                                /* A xor X */
                 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0),                                          /* A == 0 ? */
                 BPF_STMT(BPF_RET + BPF_K, 0),                                                          /* ignore */
-                BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((unsigned short *) (((char *) &mac_addr) + 4)))), /* A <- remainder of client's MAC */
+                BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((unsigned short *) (((char *) eth_mac) + 4)))),   /* A <- remainder of client's MAC */
                 BPF_STMT(BPF_MISC + BPF_TAX, 0),                                                       /* X <- A */
                 BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, dhcp.chaddr) + 4),             /* A <- remainder of MAC from dhcp.chaddr */
                 BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0),                                                /* A xor X */
@@ -107,8 +111,9 @@
         link->ll.sll_family = AF_PACKET;
         link->ll.sll_protocol = htons(ETH_P_IP);
         link->ll.sll_ifindex = ifindex;
-        link->ll.sll_halen = ETH_ALEN;
-        memset(link->ll.sll_addr, 0xff, ETH_ALEN);
+        link->ll.sll_hatype = htons(arp_type);
+        link->ll.sll_halen = mac_addr_len;
+        memcpy(link->ll.sll_addr, bcast_addr, mac_addr_len);
 
         r = bind(s, &link->sa, sizeof(link->ll));
         if (r < 0)
@@ -120,6 +125,37 @@
         return r;
 }
 
+int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,
+                                 uint32_t xid, const uint8_t *mac_addr,
+                                 size_t mac_addr_len, uint16_t arp_type) {
+        static const uint8_t eth_bcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+        /* Default broadcast address for IPoIB */
+        static const uint8_t ib_bcast[] = {
+                0x00, 0xff, 0xff, 0xff, 0xff, 0x12, 0x40, 0x1b,
+                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                0xff, 0xff, 0xff, 0xff
+          };
+        struct ether_addr eth_mac = { { 0, 0, 0, 0, 0, 0 } };
+        const uint8_t *bcast_addr = NULL;
+        uint8_t dhcp_hlen = 0;
+
+        assert_return(mac_addr_len > 0, -EINVAL);
+
+        if (arp_type == ARPHRD_ETHER) {
+                assert_return(mac_addr_len == ETH_ALEN, -EINVAL);
+                memcpy(&eth_mac, mac_addr, ETH_ALEN);
+                bcast_addr = eth_bcast;
+                dhcp_hlen = ETH_ALEN;
+        } else if (arp_type == ARPHRD_INFINIBAND) {
+                assert_return(mac_addr_len == INFINIBAND_ALEN, -EINVAL);
+                bcast_addr = ib_bcast;
+        } else
+                return -EINVAL;
+
+        return _bind_raw_socket(ifindex, link, xid, mac_addr, mac_addr_len,
+                                bcast_addr, &eth_mac, arp_type, dhcp_hlen);
+}
+
 int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) {
         union sockaddr_union src = {
                 .in.sin_family = AF_INET,
diff -urN systemd-216/src/libsystemd-network/dhcp-packet.c systemd-217/src/libsystemd-network/dhcp-packet.c
--- systemd-216/src/libsystemd-network/dhcp-packet.c	2014-06-17 04:00:39.209283403 -0700
+++ systemd-217/src/libsystemd-network/dhcp-packet.c	2014-10-13 08:19:31.019675598 -0700
@@ -38,15 +38,17 @@
 #define DHCP_CLIENT_MIN_OPTIONS_SIZE            312
 
 int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid,
-                      uint8_t type, size_t optlen, size_t *optoffset) {
+                      uint8_t type, uint16_t arp_type, size_t optlen,
+                      size_t *optoffset) {
         size_t offset = 0;
         int r;
 
         assert(op == BOOTREQUEST || op == BOOTREPLY);
+        assert(arp_type == ARPHRD_ETHER || arp_type == ARPHRD_INFINIBAND);
 
         message->op = op;
-        message->htype = ARPHRD_ETHER;
-        message->hlen = ETHER_ADDR_LEN;
+        message->htype = arp_type;
+        message->hlen = (arp_type == ARPHRD_ETHER) ? ETHER_ADDR_LEN : 0;
         message->xid = htobe32(xid);
         message->magic = htobe32(DHCP_MAGIC_COOKIE);
 
diff -urN systemd-216/src/libsystemd-network/sd-dhcp6-client.c systemd-217/src/libsystemd-network/sd-dhcp6-client.c
--- systemd-216/src/libsystemd-network/sd-dhcp6-client.c	2014-11-03 09:35:33.841236121 -0800
+++ systemd-217/src/libsystemd-network/sd-dhcp6-client.c	2014-10-13 08:19:31.020675595 -0700
@@ -22,6 +22,7 @@
 #include <errno.h>
 #include <string.h>
 #include <sys/ioctl.h>
+#include <linux/if_infiniband.h>
 
 #include "udev.h"
 #include "udev-util.h"
@@ -44,6 +45,8 @@
  */
 #define MAX_DUID_LEN 128
 
+#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
+
 struct sd_dhcp6_client {
         RefCount n_ref;
 
@@ -51,7 +54,9 @@
         sd_event *event;
         int event_priority;
         int index;
-        struct ether_addr mac_addr;
+        uint8_t mac_addr[MAX_MAC_ADDR_LEN];
+        size_t mac_addr_len;
+        uint16_t arp_type;
         DHCP6IA ia_na;
         be32_t transaction_id;
         usec_t transaction_start;
@@ -160,15 +165,28 @@
         return 0;
 }
 
-int sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
-                            const struct ether_addr *mac_addr)
+int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr,
+                            size_t addr_len, uint16_t arp_type)
 {
         assert_return(client, -EINVAL);
-
-        if (mac_addr)
-                memcpy(&client->mac_addr, mac_addr, sizeof(client->mac_addr));
+        assert_return(addr, -EINVAL);
+        assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL);
+        assert_return(arp_type > 0, -EINVAL);
+
+        if (arp_type == ARPHRD_ETHER)
+                assert_return(addr_len == ETH_ALEN, -EINVAL);
+        else if (arp_type == ARPHRD_INFINIBAND)
+                assert_return(addr_len == INFINIBAND_ALEN, -EINVAL);
         else
-                memset(&client->mac_addr, 0x00, sizeof(client->mac_addr));
+                return -EINVAL;
+
+        if (client->mac_addr_len == addr_len &&
+            memcmp(&client->mac_addr, addr, addr_len) == 0)
+                return 0;
+
+        memcpy(&client->mac_addr, addr, addr_len);
+        client->mac_addr_len = addr_len;
+        client->arp_type = arp_type;
 
         return 0;
 }
@@ -646,8 +664,8 @@
                 siphash24((uint8_t*)&id, name, strlen(name), HASH_KEY.bytes);
         else
                 /* fall back to mac address if no predictable name available */
-                siphash24((uint8_t*)&id, &client->mac_addr, ETH_ALEN,
-                          HASH_KEY.bytes);
+                siphash24((uint8_t*)&id, &client->mac_addr,
+                          client->mac_addr_len, HASH_KEY.bytes);
 
         /* fold into 32 bits */
         client->ia_na.id = (id & 0xffffffff) ^ (id >> 32);
diff -urN systemd-216/src/libsystemd-network/sd-dhcp-client.c systemd-217/src/libsystemd-network/sd-dhcp-client.c
--- systemd-216/src/libsystemd-network/sd-dhcp-client.c	2014-11-03 09:35:24.050137397 -0800
+++ systemd-217/src/libsystemd-network/sd-dhcp-client.c	2014-11-03 09:33:48.878177779 -0800
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include <net/ethernet.h>
 #include <net/if_arp.h>
+#include <linux/if_infiniband.h>
 #include <netinet/ether.h>
 #include <sys/param.h>
 #include <sys/ioctl.h>
@@ -37,6 +38,8 @@
 #include "dhcp-lease-internal.h"
 #include "sd-dhcp-client.h"
 
+#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
+
 struct sd_dhcp_client {
         RefCount n_ref;
 
@@ -57,6 +60,9 @@
                 uint8_t type;
                 struct ether_addr mac_addr;
         } _packed_ client_id;
+        uint8_t mac_addr[MAX_MAC_ADDR_LEN];
+        size_t mac_addr_len;
+        uint16_t arp_type;
         char *hostname;
         char *vendor_class_identifier;
         uint32_t mtu;
@@ -163,15 +169,25 @@
         return 0;
 }
 
-int sd_dhcp_client_set_mac(sd_dhcp_client *client,
-                           const struct ether_addr *addr) {
+int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
+                           size_t addr_len, uint16_t arp_type) {
         DHCP_CLIENT_DONT_DESTROY(client);
         bool need_restart = false;
 
         assert_return(client, -EINVAL);
         assert_return(addr, -EINVAL);
+        assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL);
+        assert_return(arp_type > 0, -EINVAL);
+
+        if (arp_type == ARPHRD_ETHER)
+                assert_return(addr_len == ETH_ALEN, -EINVAL);
+        else if (arp_type == ARPHRD_INFINIBAND)
+                assert_return(addr_len == INFINIBAND_ALEN, -EINVAL);
+        else
+                return -EINVAL;
 
-        if (memcmp(&client->client_id.mac_addr, addr, ETH_ALEN) == 0)
+        if (client->mac_addr_len == addr_len &&
+            memcmp(&client->mac_addr, addr, addr_len) == 0)
                 return 0;
 
         if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
@@ -181,6 +197,10 @@
                 client_stop(client, DHCP_EVENT_STOP);
         }
 
+        memcpy(&client->mac_addr, addr, addr_len);
+        client->mac_addr_len = addr_len;
+        client->arp_type = arp_type;
+
         memcpy(&client->client_id.mac_addr, addr, ETH_ALEN);
         client->client_id.type = 0x01;
 
@@ -318,7 +338,7 @@
                 return -ENOMEM;
 
         r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type,
-                              optlen, &optoffset);
+                              client->arp_type, optlen, &optoffset);
         if (r < 0)
                 return r;
 
@@ -337,14 +357,17 @@
            Note: some interfaces needs this to be enabled, but some networks
            needs this to be disabled as broadcasts are filteretd, so this
            needs to be configurable */
-        if (client->request_broadcast)
+        if (client->request_broadcast || client->arp_type != ARPHRD_ETHER)
                 packet->dhcp.flags = htobe16(0x8000);
 
         /* RFC2132 section 4.1.1:
            The client MUST include its hardware address in the ’chaddr’ field, if
-           necessary for delivery of DHCP reply messages.
+           necessary for delivery of DHCP reply messages.  Non-Ethernet
+           interfaces will leave 'chaddr' empty and use the client identifier
+           instead (eg, RFC 4390 section 2.1).
          */
-        memcpy(&packet->dhcp.chaddr, &client->client_id.mac_addr, ETH_ALEN);
+        if (client->arp_type == ARPHRD_ETHER)
+                memcpy(&packet->dhcp.chaddr, &client->mac_addr, ETH_ALEN);
 
         /* Some DHCP servers will refuse to issue an DHCP lease if the Client
            Identifier option is not set */
@@ -843,7 +866,9 @@
 
         client->xid = random_u32();
 
-        r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid, client->client_id.mac_addr);
+        r = dhcp_network_bind_raw_socket(client->index, &client->link,
+                                         client->xid, client->mac_addr,
+                                         client->mac_addr_len, client->arp_type);
         if (r < 0) {
                 client_stop(client, r);
                 return r;
@@ -887,7 +912,9 @@
         client->state = DHCP_STATE_REBINDING;
         client->attempt = 1;
 
-        r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid, client->client_id.mac_addr);
+        r = dhcp_network_bind_raw_socket(client->index, &client->link,
+                                         client->xid, client->mac_addr,
+                                         client->mac_addr_len, client->arp_type);
         if (r < 0) {
                 client_stop(client, r);
                 return 0;
@@ -1242,6 +1269,9 @@
                 if (r >= 0) {
                         client->timeout_resend =
                                 sd_event_source_unref(client->timeout_resend);
+                        client->receive_message =
+                                sd_event_source_unref(client->receive_message);
+                        client->fd = asynchronous_close(client->fd);
 
                         if (IN_SET(client->state, DHCP_STATE_REQUESTING,
                                    DHCP_STATE_REBOOTING))
@@ -1331,6 +1361,9 @@
         sd_dhcp_client *client = userdata;
         _cleanup_free_ DHCPMessage *message = NULL;
         int buflen = 0, len, r;
+        const struct ether_addr zero_mac = { { 0, 0, 0, 0, 0, 0 } };
+        const struct ether_addr *expected_chaddr = NULL;
+        uint8_t expected_hlen = 0;
 
         assert(s);
         assert(client);
@@ -1367,13 +1400,26 @@
                 return 0;
         }
 
-        if (message->htype != ARPHRD_ETHER || message->hlen != ETHER_ADDR_LEN) {
-                log_dhcp_client(client, "not an ethernet packet");
+        if (message->htype != client->arp_type) {
+                log_dhcp_client(client, "packet type does not match client type");
+                return 0;
+        }
+
+        if (client->arp_type == ARPHRD_ETHER) {
+                expected_hlen = ETH_ALEN;
+                expected_chaddr = (const struct ether_addr *) &client->mac_addr;
+        } else {
+               /* Non-ethernet links expect zero chaddr */
+               expected_hlen = 0;
+               expected_chaddr = &zero_mac;
+        }
+
+        if (message->hlen != expected_hlen) {
+                log_dhcp_client(client, "unexpected packet hlen %d", message->hlen);
                 return 0;
         }
 
-        if (memcmp(&message->chaddr[0], &client->client_id.mac_addr,
-                   ETH_ALEN)) {
+        if (memcmp(&message->chaddr[0], expected_chaddr, ETH_ALEN)) {
                 log_dhcp_client(client, "received chaddr does not match "
                                 "expected: ignoring");
                 return 0;
@@ -1455,7 +1501,6 @@
 }
 
 int sd_dhcp_client_start(sd_dhcp_client *client) {
-        char buffer[ETHER_ADDR_TO_STRING_MAX];
         int r;
 
         assert_return(client, -EINVAL);
@@ -1469,9 +1514,7 @@
 
         r = client_start(client);
         if (r >= 0)
-                log_dhcp_client(client, "STARTED on ifindex %u with address %s",
-                                client->index,
-                                ether_addr_to_string(&client->client_id.mac_addr, buffer));
+                log_dhcp_client(client, "STARTED on ifindex %u", client->index);
 
         return r;
 }
diff -urN systemd-216/src/libsystemd-network/sd-dhcp-lease.c systemd-217/src/libsystemd-network/sd-dhcp-lease.c
--- systemd-216/src/libsystemd-network/sd-dhcp-lease.c	2014-08-14 18:10:20.526067414 -0700
+++ systemd-217/src/libsystemd-network/sd-dhcp-lease.c	2014-10-27 10:09:26.605862018 -0700
@@ -30,6 +30,7 @@
 #include "list.h"
 #include "mkdir.h"
 #include "fileio.h"
+#include "in-addr-util.h"
 
 #include "dhcp-protocol.h"
 #include "dhcp-internal.h"
@@ -803,27 +804,20 @@
 }
 
 int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) {
-        uint32_t address;
+        struct in_addr address;
+        struct in_addr mask;
+        int r;
 
         assert(lease);
-        assert(lease->address != INADDR_ANY);
 
-        address = be32toh(lease->address);
+        address.s_addr = lease->address;
 
         /* fall back to the default subnet masks based on address class */
+        r = in_addr_default_subnet_mask(&address, &mask);
+        if (r < 0)
+                return r;
 
-        if ((address >> 31) == 0x0)
-                /* class A, leading bits: 0 */
-                lease->subnet_mask = htobe32(0xff000000);
-        else if ((address >> 30) == 0x2)
-                /* class B, leading bits 10 */
-                lease->subnet_mask = htobe32(0xffff0000);
-        else if ((address >> 29) == 0x6)
-                /* class C, leading bits 110 */
-                lease->subnet_mask = htobe32(0xffffff00);
-        else
-                /* class D or E, no default mask. give up */
-                return -ERANGE;
+        lease->subnet_mask = mask.s_addr;
 
         return 0;
 }
diff -urN systemd-216/src/libsystemd-network/sd-dhcp-server.c systemd-217/src/libsystemd-network/sd-dhcp-server.c
--- systemd-216/src/libsystemd-network/sd-dhcp-server.c	2014-11-03 09:35:27.863175844 -0800
+++ systemd-217/src/libsystemd-network/sd-dhcp-server.c	2014-10-13 08:19:31.019675598 -0700
@@ -392,8 +392,8 @@
                 return -ENOMEM;
 
         r = dhcp_message_init(&packet->dhcp, BOOTREPLY,
-                              be32toh(req->message->xid), type, req->max_optlen,
-                              &optoffset);
+                              be32toh(req->message->xid), type, ARPHRD_ETHER,
+                              req->max_optlen, &optoffset);
         if (r < 0)
                 return r;
 
@@ -513,8 +513,8 @@
                 return -ENOMEM;
 
         r = dhcp_message_init(&packet->dhcp, BOOTREPLY, 0,
-                              DHCP_FORCERENEW, DHCP_MIN_OPTIONS_SIZE,
-                              &optoffset);
+                              DHCP_FORCERENEW, ARPHRD_ETHER,
+                              DHCP_MIN_OPTIONS_SIZE, &optoffset);
         if (r < 0)
                 return r;
 
diff -urN systemd-216/src/libsystemd-network/test-dhcp6-client.c systemd-217/src/libsystemd-network/test-dhcp6-client.c
--- systemd-216/src/libsystemd-network/test-dhcp6-client.c	2014-11-03 09:35:26.964166780 -0800
+++ systemd-217/src/libsystemd-network/test-dhcp6-client.c	2014-10-13 08:19:31.020675595 -0700
@@ -66,7 +66,9 @@
         assert_se(sd_dhcp6_client_set_index(client, -1) == 0);
         assert_se(sd_dhcp6_client_set_index(client, 42) >= 0);
 
-        assert_se(sd_dhcp6_client_set_mac(client, &mac_addr) >= 0);
+        assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
+                                          sizeof (mac_addr),
+                                          ARPHRD_ETHER) >= 0);
 
         assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_CLIENTID) == -EINVAL);
         assert_se(sd_dhcp6_client_set_request_option(client, DHCP6_OPTION_DNS_SERVERS) == -EEXIST);
@@ -572,7 +574,9 @@
         assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
 
         assert_se(sd_dhcp6_client_set_index(client, test_index) == 0);
-        assert_se(sd_dhcp6_client_set_mac(client, &mac_addr) >= 0);
+        assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
+                                          sizeof (mac_addr),
+                                          ARPHRD_ETHER) >= 0);
 
         assert_se(sd_dhcp6_client_set_callback(client,
                                                test_client_solicit_cb, e) >= 0);
diff -urN systemd-216/src/libsystemd-network/test-dhcp-client.c systemd-217/src/libsystemd-network/test-dhcp-client.c
--- systemd-216/src/libsystemd-network/test-dhcp-client.c	2014-07-29 10:51:00.728285844 -0700
+++ systemd-217/src/libsystemd-network/test-dhcp-client.c	2014-10-13 08:19:31.020675595 -0700
@@ -196,7 +196,9 @@
         return 575;
 }
 
-int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, uint32_t id, struct ether_addr mac)
+int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link,
+                                 uint32_t id, const uint8_t *addr,
+                                 size_t addr_len, uint16_t arp_type)
 {
         if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0)
                 return -errno;
@@ -244,7 +246,10 @@
         assert_se(r >= 0);
 
         assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
-        assert_se(sd_dhcp_client_set_mac(client, &mac_addr) >= 0);
+        assert_se(sd_dhcp_client_set_mac(client,
+                                         (const uint8_t *) &mac_addr,
+                                         sizeof (mac_addr),
+                                         ARPHRD_ETHER) >= 0);
 
         assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0);
 
@@ -462,7 +467,10 @@
         assert_se(r >= 0);
 
         assert_se(sd_dhcp_client_set_index(client, 42) >= 0);
-        assert_se(sd_dhcp_client_set_mac(client, &mac_addr) >= 0);
+        assert_se(sd_dhcp_client_set_mac(client,
+                                         (const uint8_t *) &mac_addr,
+                                         sizeof (mac_addr),
+                                         ARPHRD_ETHER) >= 0);
 
         assert_se(sd_dhcp_client_set_callback(client, test_addr_acq_acquired, e)
                 >= 0);
@@ -477,12 +485,12 @@
         res = sd_dhcp_client_start(client);
         assert_se(res == 0 || res == -EINPROGRESS);
 
-        sd_event_loop(e);
+        assert_se(sd_event_loop(e) >= 0);
 
         test_hangcheck = sd_event_source_unref(test_hangcheck);
 
-        sd_dhcp_client_set_callback(client, NULL, NULL);
-        sd_dhcp_client_stop(client);
+        assert_se(sd_dhcp_client_set_callback(client, NULL, NULL) >= 0);
+        assert_se(sd_dhcp_client_stop(client) >= 0);
         sd_dhcp_client_unref(client);
 
         test_fd[1] = safe_close(test_fd[1]);
diff -urN systemd-216/src/libsystemd-network/test-dhcp-option.c systemd-217/src/libsystemd-network/test-dhcp-option.c
--- systemd-216/src/libsystemd-network/test-dhcp-option.c	2014-11-03 09:35:28.940186704 -0800
+++ systemd-217/src/libsystemd-network/test-dhcp-option.c	2014-10-13 08:19:31.020675595 -0700
@@ -92,7 +92,7 @@
         message = malloc0(len);
 
         assert_se(dhcp_message_init(message, BOOTREQUEST, 0x12345678,
-                  DHCP_DISCOVER, optlen, &optoffset) >= 0);
+                  DHCP_DISCOVER, ARPHRD_ETHER, optlen, &optoffset) >= 0);
 
         assert_se(message->xid == htobe32(0x12345678));
         assert_se(message->op == BOOTREQUEST);
diff -urN systemd-216/src/libsystemd-terminal/grdev-drm.c systemd-217/src/libsystemd-terminal/grdev-drm.c
--- systemd-216/src/libsystemd-terminal/grdev-drm.c	2014-11-03 09:35:34.417241929 -0800
+++ systemd-217/src/libsystemd-terminal/grdev-drm.c	2014-10-13 08:19:31.021675591 -0700
@@ -1158,8 +1158,21 @@
         assert(basefb);
         assert(pipe);
 
-        if (!crtc->applied && !grdrm_modes_compatible(&crtc->kern.mode, &crtc->set.mode))
+        if (!crtc->applied) {
+                if (!grdrm_modes_compatible(&crtc->kern.mode, &crtc->set.mode))
+                        return 0;
+
+                /* TODO: Theoretically, we should be able to page-flip to our
+                 * framebuffer here. We didn't perform any deep modeset, but the
+                 * DRM driver is really supposed to reject our page-flip in case
+                 * the FB is not compatible. We then properly fall back to a
+                 * deep modeset.
+                 * As it turns out, drivers don't to this. Therefore, we need to
+                 * perform a full modeset on enter now. We might avoid this in
+                 * the future with fixed drivers.. */
+
                 return 0;
+        }
 
         fb = fb_from_base(basefb);
 
diff -urN systemd-216/src/libsystemd-terminal/term-screen.c systemd-217/src/libsystemd-terminal/term-screen.c
--- systemd-216/src/libsystemd-terminal/term-screen.c	2014-11-03 09:35:35.423252073 -0800
+++ systemd-217/src/libsystemd-terminal/term-screen.c	2014-10-17 04:49:07.965593679 -0700
@@ -392,126 +392,117 @@
                 screen->flags &= ~flag;
 }
 
-static void screen_mode_change(term_screen *screen, unsigned int mode, bool dec, bool set) {
+static void screen_mode_change_ansi(term_screen *screen, unsigned mode, bool set) {
+        switch (mode) {
+        case 20:
+                /*
+                 * LNM: line-feed/new-line mode
+                 * TODO
+                 */
+                set_reset(screen, TERM_FLAG_NEWLINE_MODE, set);
+
+                break;
+        default:
+                log_debug("terminal: failed to %s unknown ANSI mode %u", set ? "set" : "unset", mode);
+        }
+}
+
+static void screen_mode_change_dec(term_screen *screen, unsigned int mode, bool set) {
         switch (mode) {
         case 1:
-                if (dec) {
-                        /*
-                         * DECCKM: cursor-keys
-                         * TODO
-                         */
-                        set_reset(screen, TERM_FLAG_CURSOR_KEYS, set);
-                }
+                /*
+                 * DECCKM: cursor-keys
+                 * TODO
+                 */
+                set_reset(screen, TERM_FLAG_CURSOR_KEYS, set);
 
                 break;
         case 6:
-                if (dec) {
-                        /*
-                         * DECOM: origin-mode
-                         * TODO
-                         */
-                        screen->state.origin_mode = set;
-                }
+                /*
+                 * DECOM: origin-mode
+                 * TODO
+                 */
+                screen->state.origin_mode = set;
 
                 break;
         case 7:
-                if (dec) {
-                        /*
-                         * DECAWN: auto-wrap mode
-                         * TODO
-                         */
-                        screen->state.auto_wrap = set;
-                }
-
-                break;
-        case 20:
-                if (!dec) {
-                        /*
-                         * LNM: line-feed/new-line mode
-                         * TODO
-                         */
-                        set_reset(screen, TERM_FLAG_NEWLINE_MODE, set);
-                }
+                /*
+                 * DECAWN: auto-wrap mode
+                 * TODO
+                 */
+                screen->state.auto_wrap = set;
 
                 break;
         case 25:
-                if (dec) {
-                        /*
-                         * DECTCEM: text-cursor-enable
-                         * TODO
-                         */
-                        set_reset(screen, TERM_FLAG_HIDE_CURSOR, !set);
-                        screen_age_cursor(screen);
-                }
+                /*
+                 * DECTCEM: text-cursor-enable
+                 * TODO
+                 */
+                set_reset(screen, TERM_FLAG_HIDE_CURSOR, !set);
+                screen_age_cursor(screen);
 
                 break;
         case 47:
-                if (dec) {
-                        /*
-                         * XTERM-ASB: alternate-screen-buffer
-                         * This enables/disables the alternate screen-buffer.
-                         * It effectively saves the current page content and
-                         * allows you to restore it when changing to the
-                         * original screen-buffer again.
-                         */
-                        screen_change_alt(screen, set);
-                }
+                /*
+                 * XTERM-ASB: alternate-screen-buffer
+                 * This enables/disables the alternate screen-buffer.
+                 * It effectively saves the current page content and
+                 * allows you to restore it when changing to the
+                 * original screen-buffer again.
+                 */
+                screen_change_alt(screen, set);
 
                 break;
         case 1047:
-                if (dec) {
-                        /*
-                         * XTERM-ASBPE: alternate-screen-buffer-post-erase
-                         * This is the same as XTERM-ASB but erases the
-                         * alternate screen-buffer before switching back to the
-                         * original buffer. Use it to discard any data on the
-                         * alternate screen buffer when done.
-                         */
-                        if (!set)
-                                screen_reset_page(screen, screen->page_alt);
+                /*
+                 * XTERM-ASBPE: alternate-screen-buffer-post-erase
+                 * This is the same as XTERM-ASB but erases the
+                 * alternate screen-buffer before switching back to the
+                 * original buffer. Use it to discard any data on the
+                 * alternate screen buffer when done.
+                 */
+                if (!set)
+                        screen_reset_page(screen, screen->page_alt);
 
-                        screen_change_alt(screen, set);
-                }
+                screen_change_alt(screen, set);
 
                 break;
         case 1048:
-                if (dec) {
-                        /*
-                         * XTERM-ASBCS: alternate-screen-buffer-cursor-state
-                         * This has the same effect as DECSC/DECRC, but uses a
-                         * separate state buffer. It is usually used in
-                         * combination with alternate screen buffers to provide
-                         * stacked state storage.
-                         */
-                        if (set)
-                                screen_save_state(screen, &screen->saved_alt);
-                        else
-                                screen_restore_state(screen, &screen->saved_alt);
-                }
+                /*
+                 * XTERM-ASBCS: alternate-screen-buffer-cursor-state
+                 * This has the same effect as DECSC/DECRC, but uses a
+                 * separate state buffer. It is usually used in
+                 * combination with alternate screen buffers to provide
+                 * stacked state storage.
+                 */
+                if (set)
+                        screen_save_state(screen, &screen->saved_alt);
+                else
+                        screen_restore_state(screen, &screen->saved_alt);
 
                 break;
         case 1049:
-                if (dec) {
-                        /*
-                         * XTERM-ASBX: alternate-screen-buffer-extended
-                         * This combines XTERM-ASBPE and XTERM-ASBCS somewhat.
-                         * When enabling, state is saved, alternate screen
-                         * buffer is activated and cleared.
-                         * When disabled, alternate screen buffer is cleared,
-                         * then normal screen buffer is enabled and state is
-                         * restored.
-                         */
-                        if (set)
-                                screen_save_state(screen, &screen->saved_alt);
+                /*
+                 * XTERM-ASBX: alternate-screen-buffer-extended
+                 * This combines XTERM-ASBPE and XTERM-ASBCS somewhat.
+                 * When enabling, state is saved, alternate screen
+                 * buffer is activated and cleared.
+                 * When disabled, alternate screen buffer is cleared,
+                 * then normal screen buffer is enabled and state is
+                 * restored.
+                 */
+                if (set)
+                        screen_save_state(screen, &screen->saved_alt);
+
+                screen_reset_page(screen, screen->page_alt);
+                screen_change_alt(screen, set);
 
-                        screen_reset_page(screen, screen->page_alt);
-                        screen_change_alt(screen, set);
-
-                        if (!set)
-                                screen_restore_state(screen, &screen->saved_alt);
-                }
+                if (!set)
+                        screen_restore_state(screen, &screen->saved_alt);
 
                 break;
+        default:
+                log_debug("terminal: failed to %s unknown DEC mode %u", set ? "set" : "unset", mode);
         }
 }
 
@@ -2763,7 +2754,7 @@
         unsigned int i;
 
         for (i = 0; i < seq->n_args; ++i)
-                screen_mode_change(screen, seq->args[i], false, false);
+                screen_mode_change_ansi(screen, seq->args[i], false);
 
         return 0;
 }
@@ -2777,7 +2768,7 @@
         unsigned int i;
 
         for (i = 0; i < seq->n_args; ++i)
-                screen_mode_change(screen, seq->args[i], true, false);
+                screen_mode_change_dec(screen, seq->args[i], false);
 
         return 0;
 }
@@ -3057,7 +3048,7 @@
         unsigned int i;
 
         for (i = 0; i < seq->n_args; ++i)
-                screen_mode_change(screen, seq->args[i], false, true);
+                screen_mode_change_ansi(screen, seq->args[i], true);
 
         return 0;
 }
@@ -3071,7 +3062,7 @@
         unsigned int i;
 
         for (i = 0; i < seq->n_args; ++i)
-                screen_mode_change(screen, seq->args[i], true, true);
+                screen_mode_change_dec(screen, seq->args[i], true);
 
         return 0;
 }
diff -urN systemd-216/src/libsystemd-terminal/unifont-def.h systemd-217/src/libsystemd-terminal/unifont-def.h
--- systemd-216/src/libsystemd-terminal/unifont-def.h	1969-12-31 16:00:00.000000000 -0800
+++ systemd-217/src/libsystemd-terminal/unifont-def.h	2014-10-07 06:59:01.461580544 -0700
@@ -0,0 +1,137 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
+
+  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/>.
+***/
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "sparse-endian.h"
+#include "util.h"
+
+typedef struct unifont_header unifont_header;
+typedef struct unifont_glyph_header unifont_glyph_header;
+
+/*
+ * Unifont: On-disk data
+ * Conventional font-formats have the problem that you have to pre-render each
+ * glyph before you can use it. If you just need one glyph, you have to parse
+ * the font-file until you found that glyph.
+ * GNU-Unifont is a bitmap font with very good Unicode coverage. All glyphs are
+ * (n*8)x16 bitmaps. Our on-disk data stores all those glyphs pre-compiled with
+ * fixed offsets. Therefore, the font-file can be mmap()ed and all glyphs can
+ * be accessed in O(1) (because all glyphs have the same size and thus their
+ * offsets can be easily computed). This guarantees, that the kernel only loads
+ * the pages that are really accessed. Thus, we have a far lower overhead than
+ * traditional font-formats like BDF. Furthermore, the backing file is read-only
+ * and can be shared in memory between multiple users.
+ *
+ * The binary-format starts with a fixed header:
+ *
+ *      | 2bytes | 2bytes | 2bytes | 2bytes |
+ *
+ *      +-----------------------------------+
+ *      |             SIGNATURE             |   8 bytes
+ *      +-----------------+-----------------+
+ *      |  COMPAT FLAGS   | INCOMPAT FLAGS  |   8 bytes
+ *      +-----------------+--------+--------+
+ *      |   HEADER SIZE   |GH-SIZE |G-STRIDE|   8 bytes
+ *      +-----------------+--------+--------+
+ *      |          GLYPH BODY SIZE          |   8 bytes
+ *      +-----------------------------------+
+ *
+ *  * The 8 bytes signature must be set to the ASCII string "DVDHRMUF".
+ *  * The 4 bytes compatible-flags field contains flags for new features that
+ *    might be added in the future and which are compatible to older parsers.
+ *  * The 4 bytes incompatible-flags field contains flags for new features that
+ *    might be added in the future and which are incompatible to old parses.
+ *    Thus, if you encounter an unknown bit set, you must abort!
+ *  * The 4 bytes header-size field contains the size of the header in bytes. It
+ *    must be at least 32 (the size of this fixed header). If new features are
+ *    added, it might be increased. It can also be used to add padding to the
+ *    end of the header.
+ *  * The 2 bytes glyph-header-size field specifies the size of each glyph
+ *    header in bytes (see below).
+ *  * The 2 bytes glyph-stride field specifies the stride of each line of glyph
+ *    data in "bytes per line".
+ *  * The 8 byte glyph-body-size field defines the size of each glyph body in
+ *    bytes.
+ *
+ * After the header, the file can contain padding bytes, depending on the
+ * header-size field. Everything beyond the header+padding is treated as a big
+ * array of glyphs. Each glyph looks like this:
+ *
+ *      |              1 byte               |
+ *
+ *      +-----------------------------------+
+ *      |               WIDTH               |   1 byte
+ *      +-----------------------------------+
+ *      ~              PADDING              ~
+ *      +-----------------------------------+
+ *      ~                                   ~
+ *      ~                                   ~
+ *      ~                DATA               ~
+ *      ~                                   ~
+ *      ~                                   ~
+ *      +-----------------------------------+
+ *
+ *  * The first byte specifies the width of the glyph. If it is 0, the glyph
+ *    must be treated as non-existant.
+ *    All glyphs are "8*n" pixels wide and "16" pixels high. The width-field
+ *    specifies the width multiplier "n".
+ *  * After the width field padding might be added. This depends on the global
+ *    glyph-header-size field. It defines the total size of each glyph-header.
+ *    After the glyph-header+padding, the data-field starts.
+ *  * The data-field contains a byte-array of bitmap data. The array is always
+ *    as big as specified in the global glyph-body-size header field. This might
+ *    include padding.
+ *    The array contains all 16 lines of bitmap information for that glyph. The
+ *    stride is given in the global glyph-stride header field. This can be used
+ *    to add padding after each line.
+ *    Each line is encoded as 1 bit per pixel bitmap. That is, each byte encodes
+ *    data for 8 pixels (left most pixel is encoded in the LSB, right most pixel
+ *    in the MSB). The width field defines the number of bytes valid per line.
+ *    For width==1, you need 1 byte to encode the 8 pixels. The stride defines
+ *    where the encoding of the next line starts.
+ *    Any data beyond the 16th line is padding and must be ignored.
+ */
+
+/* path to binary file */
+#define UNIFONT_PATH "/usr/share/systemd/unifont-glyph-array.bin"
+
+/* header-size of version 1 */
+#define UNIFONT_HEADER_SIZE_MIN 32
+
+struct unifont_header {
+        /* fields available in version 1 */
+        uint8_t signature[8];
+        le32_t compatible_flags;
+        le32_t incompatible_flags;
+        le32_t header_size;
+        le16_t glyph_header_size;
+        le16_t glyph_stride;
+        le64_t glyph_body_size;
+} _packed_;
+
+struct unifont_glyph_header {
+        /* fields available in version 1 */
+        uint8_t width;
+} _packed_;
diff -urN systemd-216/src/libudev/libudev.c systemd-217/src/libudev/libudev.c
--- systemd-216/src/libudev/libudev.c	2014-03-18 10:05:49.964378252 -0700
+++ systemd-217/src/libudev/libudev.c	2014-11-03 09:33:49.192180945 -0800
@@ -119,7 +119,7 @@
 {
         struct udev *udev;
         const char *env;
-        FILE *f;
+        _cleanup_fclose_ FILE *f = NULL;
 
         udev = new0(struct udev, 1);
         if (udev == NULL)
@@ -132,7 +132,7 @@
         f = fopen("/etc/udev/udev.conf", "re");
         if (f != NULL) {
                 char line[UTIL_LINE_SIZE];
-                int line_nr = 0;
+                unsigned line_nr = 0;
 
                 while (fgets(line, sizeof(line), f)) {
                         size_t len;
@@ -153,7 +153,7 @@
                         /* split key/value */
                         val = strchr(key, '=');
                         if (val == NULL) {
-                                udev_err(udev, "missing <key>=<value> in /etc/udev/udev.conf[%i]; skip line\n", line_nr);
+                                udev_err(udev, "/etc/udev/udev.conf:%u: missing assignment,  skipping line.\n", line_nr);
                                 continue;
                         }
                         val[0] = '\0';
@@ -185,7 +185,7 @@
                         /* unquote */
                         if (val[0] == '"' || val[0] == '\'') {
                                 if (val[len-1] != val[0]) {
-                                        udev_err(udev, "inconsistent quoting in /etc/udev/udev.conf[%i]; skip line\n", line_nr);
+                                        udev_err(udev, "/etc/udev/udev.conf:%u: inconsistent quoting, skipping line.\n", line_nr);
                                         continue;
                                 }
                                 val[len-1] = '\0';
@@ -193,17 +193,29 @@
                         }
 
                         if (streq(key, "udev_log")) {
-                                udev_set_log_priority(udev, util_log_priority(val));
+                                int prio;
+
+                                prio = util_log_priority(val);
+                                if (prio < 0)
+                                        udev_err(udev, "/etc/udev/udev.conf:%u: invalid logging level '%s', ignoring.\n", line_nr, val);
+                                else
+                                        udev_set_log_priority(udev, prio);
                                 continue;
                         }
                 }
-                fclose(f);
         }
 
         /* environment overrides config */
         env = secure_getenv("UDEV_LOG");
-        if (env != NULL)
-                udev_set_log_priority(udev, util_log_priority(env));
+        if (env != NULL) {
+                int prio;
+
+                prio = util_log_priority(env);
+                if (prio < 0)
+                        udev_err(udev, "$UDEV_LOG specifies invalid logging level '%s', ignoring.\n", env);
+                else
+                        udev_set_log_priority(udev, prio);
+        }
 
         return udev;
 }
diff -urN systemd-216/src/libudev/libudev-hwdb.c systemd-217/src/libudev/libudev-hwdb.c
--- systemd-216/src/libudev/libudev-hwdb.c	2014-08-04 05:58:48.292250117 -0700
+++ systemd-217/src/libudev/libudev-hwdb.c	2014-10-28 06:31:25.105131602 -0700
@@ -256,6 +256,11 @@
         return 0;
 }
 
+static const char hwdb_bin_paths[] =
+    "/etc/udev/hwdb.bin\0"
+    UDEVLIBEXECDIR "/hwdb.bin\0";
+
+
 /**
  * udev_hwdb_new:
  * @udev: udev library context
@@ -266,6 +271,7 @@
  **/
 _public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) {
         struct udev_hwdb *hwdb;
+        const char *hwdb_bin_path;
         const char sig[] = HWDB_SIG;
 
         hwdb = new0(struct udev_hwdb, 1);
@@ -275,30 +281,43 @@
         hwdb->refcount = 1;
         udev_list_init(udev, &hwdb->properties_list, true);
 
-        hwdb->f = fopen("/etc/udev/hwdb.bin", "re");
+        /* find hwdb.bin in hwdb_bin_paths */
+        NULSTR_FOREACH(hwdb_bin_path, hwdb_bin_paths) {
+                hwdb->f = fopen(hwdb_bin_path, "re");
+                if (hwdb->f)
+                        break;
+                else if (errno == ENOENT)
+                        continue;
+                else {
+                        udev_dbg(udev, "error reading %s: %m", hwdb_bin_path);
+                        udev_hwdb_unref(hwdb);
+                        return NULL;
+                }
+        }
+
         if (!hwdb->f) {
-                udev_dbg(udev, "error reading /etc/udev/hwdb.bin: %m");
+                udev_err(udev, "hwdb.bin does not exist, please run udevadm hwdb --update");
                 udev_hwdb_unref(hwdb);
                 return NULL;
         }
 
         if (fstat(fileno(hwdb->f), &hwdb->st) < 0 ||
             (size_t)hwdb->st.st_size < offsetof(struct trie_header_f, strings_len) + 8) {
-                udev_dbg(udev, "error reading /etc/udev/hwdb.bin: %m");
+                udev_dbg(udev, "error reading %s: %m", hwdb_bin_path);
                 udev_hwdb_unref(hwdb);
                 return NULL;
         }
 
         hwdb->map = mmap(0, hwdb->st.st_size, PROT_READ, MAP_SHARED, fileno(hwdb->f), 0);
         if (hwdb->map == MAP_FAILED) {
-                udev_dbg(udev, "error mapping /etc/udev/hwdb.bin: %m");
+                udev_dbg(udev, "error mapping %s: %m", hwdb_bin_path);
                 udev_hwdb_unref(hwdb);
                 return NULL;
         }
 
         if (memcmp(hwdb->map, sig, sizeof(hwdb->head->signature)) != 0 ||
             (size_t)hwdb->st.st_size != le64toh(hwdb->head->file_size)) {
-                udev_dbg(udev, "error recognizing the format of /etc/udev/hwdb.bin");
+                udev_dbg(udev, "error recognizing the format of %s", hwdb_bin_path);
                 udev_hwdb_unref(hwdb);
                 return NULL;
         }
@@ -352,14 +371,25 @@
 }
 
 bool udev_hwdb_validate(struct udev_hwdb *hwdb) {
+        bool found = false;
+        const char* p;
         struct stat st;
 
         if (!hwdb)
                 return false;
         if (!hwdb->f)
                 return false;
-        if (stat("/etc/udev/hwdb.bin", &st) < 0)
+
+        /* if hwdb.bin doesn't exist anywhere, we need to update */
+        NULSTR_FOREACH(p, hwdb_bin_paths) {
+                if (stat(p, &st) >= 0) {
+                        found = true;
+                        break;
+                }
+        }
+        if (!found)
                 return true;
+
         if (timespec_load(&hwdb->st.st_mtim) != timespec_load(&st.st_mtim))
                 return true;
         return false;
diff -urN systemd-216/src/libudev/libudev-util.c systemd-217/src/libudev/libudev-util.c
--- systemd-216/src/libudev/libudev-util.c	2014-11-03 09:35:28.399181249 -0800
+++ systemd-217/src/libudev/libudev-util.c	2014-11-03 09:33:49.044179453 -0800
@@ -159,9 +159,13 @@
         char *endptr;
         int prio;
 
-        prio = strtol(priority, &endptr, 10);
-        if (endptr[0] == '\0' || isspace(endptr[0]))
-                return prio;
+        prio = strtoul(priority, &endptr, 10);
+        if (endptr[0] == '\0' || isspace(endptr[0])) {
+                if (prio >= 0 && prio <= 7)
+                        return prio;
+                else
+                        return -ERANGE;
+        }
 
         return log_level_from_string(priority);
 }
diff -urN systemd-216/src/locale/kbd-model-map systemd-217/src/locale/kbd-model-map
--- systemd-216/src/locale/kbd-model-map	2013-12-10 08:52:49.385960774 -0800
+++ systemd-217/src/locale/kbd-model-map	2014-10-13 08:19:31.023675584 -0700
@@ -16,7 +16,6 @@
 hu101			hu	pc105		qwerty		terminate:ctrl_alt_bksp
 jp106			jp	jp106		-		terminate:ctrl_alt_bksp
 croat			hr	pc105		-		terminate:ctrl_alt_bksp
-fi-latin1		fi	pc105		-		terminate:ctrl_alt_bksp
 it2			it	pc105		-		terminate:ctrl_alt_bksp
 hu			hu	pc105		-		terminate:ctrl_alt_bksp
 sr-latin		rs	pc105		latin		terminate:ctrl_alt_bksp
diff -urN systemd-216/src/locale/localed.c systemd-217/src/locale/localed.c
--- systemd-216/src/locale/localed.c	2014-11-03 09:35:31.295210449 -0800
+++ systemd-217/src/locale/localed.c	2014-10-23 08:13:15.775717913 -0700
@@ -1141,7 +1141,7 @@
         log_open();
 
         umask(0022);
-        label_init("/etc");
+        mac_selinux_init("/etc");
 
         if (argc != 1) {
                 log_error("This program takes no arguments.");
diff -urN systemd-216/src/login/logind-dbus.c systemd-217/src/login/logind-dbus.c
--- systemd-216/src/login/logind-dbus.c	2014-11-03 09:35:22.671123493 -0800
+++ systemd-217/src/login/logind-dbus.c	2014-10-23 08:13:15.776717917 -0700
@@ -1143,7 +1143,7 @@
                 return -ENOMEM;
 
         mkdir_p_label("/etc/udev/rules.d", 0755);
-        label_init("/etc");
+        mac_selinux_init("/etc");
         r = write_string_file_atomic_label(file, rule);
         if (r < 0)
                 return r;
diff -urN systemd-216/src/login/logind-user.c systemd-217/src/login/logind-user.c
--- systemd-216/src/login/logind-user.c	2014-11-03 09:35:36.481262741 -0800
+++ systemd-217/src/login/logind-user.c	2014-10-23 08:23:34.759675549 -0700
@@ -326,7 +326,7 @@
 
                 mkdir(p, 0700);
 
-                if (use_smack())
+                if (mac_smack_use())
                         r = asprintf(&t, "mode=0700,smackfsroot=*,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size);
                 else
                         r = asprintf(&t, "mode=0700,uid=" UID_FMT ",gid=" GID_FMT ",size=%zu", u->uid, u->gid, u->manager->runtime_dir_size);
diff -urN systemd-216/src/machine/machined.c systemd-217/src/machine/machined.c
--- systemd-216/src/machine/machined.c	2014-11-03 09:35:27.869175905 -0800
+++ systemd-217/src/machine/machined.c	2014-10-23 12:36:56.910756036 -0700
@@ -35,6 +35,7 @@
 #include "bus-util.h"
 #include "bus-error.h"
 #include "machined.h"
+#include "label.h"
 
 Manager *manager_new(void) {
         Manager *m;
diff -urN systemd-216/src/network/networkd-address.c systemd-217/src/network/networkd-address.c
--- systemd-216/src/network/networkd-address.c	2014-08-13 05:09:51.594814003 -0700
+++ systemd-217/src/network/networkd-address.c	2014-10-27 10:09:26.607862012 -0700
@@ -482,7 +482,7 @@
                 r = safe_atou(e + 1, &i);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                                   "Interface prefix length is invalid, ignoring assignment: %s", e + 1);
+                                   "Prefix length is invalid, ignoring assignment: %s", e + 1);
                         return 0;
                 }
 
@@ -499,6 +499,15 @@
                 return 0;
         }
 
+        if (!e && f == AF_INET) {
+                r = in_addr_default_prefixlen(&buffer.in, &n->prefixlen);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
+                                   "Prefix length not specified, and a default one can not be deduced for '%s', ignoring assignment", address);
+                        return 0;
+                }
+        }
+
         if (n->family != AF_UNSPEC && f != n->family) {
                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
                            "Address is incompatible, ignoring assignment: %s", address);
diff -urN systemd-216/src/network/networkd-dhcp4.c systemd-217/src/network/networkd-dhcp4.c
--- systemd-216/src/network/networkd-dhcp4.c	2014-11-03 09:35:28.909186391 -0800
+++ systemd-217/src/network/networkd-dhcp4.c	2014-10-13 08:19:31.024675581 -0700
@@ -599,7 +599,9 @@
         if (r < 0)
                 return r;
 
-        r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac);
+        r = sd_dhcp_client_set_mac(link->dhcp_client,
+                                   (const uint8_t *) &link->mac,
+                                   sizeof (link->mac), ARPHRD_ETHER);
         if (r < 0)
                 return r;
 
diff -urN systemd-216/src/network/networkd-link.c systemd-217/src/network/networkd-link.c
--- systemd-216/src/network/networkd-link.c	2014-11-03 09:35:32.686224475 -0800
+++ systemd-217/src/network/networkd-link.c	2014-10-27 04:48:29.294966275 -0700
@@ -344,15 +344,6 @@
                 }
         }
 
-        if (link->dhcp_server) {
-                k = sd_dhcp_server_stop(link->dhcp_server);
-                if (k < 0) {
-                        log_warning_link(link, "Could not stop DHCPv4 server: %s",
-                                         strerror(-r));
-                        r = k;
-                }
-        }
-
         if(link->icmp6_router_discovery) {
 
                 if (link->dhcp6_client) {
@@ -909,7 +900,9 @@
                 return;
         }
 
-        r = sd_dhcp6_client_set_mac(link->dhcp6_client, &link->mac);
+        r = sd_dhcp6_client_set_mac(link->dhcp6_client,
+                                    (const uint8_t *) &link->mac,
+                                    sizeof (link->mac), ARPHRD_ETHER);
         if (r < 0) {
                 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
                 return;
@@ -1647,7 +1640,9 @@
 
                         if (link->dhcp_client) {
                                 r = sd_dhcp_client_set_mac(link->dhcp_client,
-                                                           &link->mac);
+                                                           (const uint8_t *) &link->mac,
+                                                           sizeof (link->mac),
+                                                           ARPHRD_ETHER);
                                 if (r < 0) {
                                         log_warning_link(link,
                                                          "Could not update MAC address in DHCP client: %s",
@@ -1658,7 +1653,9 @@
 
                         if (link->dhcp6_client) {
                                 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
-                                                            &link->mac);
+                                                            (const uint8_t *) &link->mac,
+                                                            sizeof (link->mac),
+                                                            ARPHRD_ETHER);
                                 if (r < 0) {
                                         log_warning_link(link,
                                                          "Could not update MAC address in DHCPv6 client: %s",
diff -urN systemd-216/src/nspawn/nspawn.c systemd-217/src/nspawn/nspawn.c
--- systemd-216/src/nspawn/nspawn.c	2014-11-03 09:35:37.063268609 -0800
+++ systemd-217/src/nspawn/nspawn.c	2014-11-03 09:33:48.969178697 -0800
@@ -758,7 +758,7 @@
                  * and char devices. */
                 if (S_ISDIR(source_st.st_mode)) {
                         r = mkdir_label(where, 0755);
-                        if (r < 0) {
+                        if (r < 0 && errno != EEXIST) {
                                 log_error("Failed to create mount point %s: %s", where, strerror(-r));
 
                                 return r;
@@ -1289,7 +1289,7 @@
         if (arg_share_system)
                 return 0;
 
-        if (sethostname(arg_machine, strlen(arg_machine)) < 0)
+        if (sethostname_idempotent(arg_machine) < 0)
                 return -errno;
 
         return 0;
@@ -1545,7 +1545,7 @@
                         return r;
                 }
 
-                r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 10,
+                r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 11,
                                           /* Allow the container to
                                            * access and create the API
                                            * device nodes, so that
@@ -2911,8 +2911,8 @@
  *       container argument.
  * > 0 : The program executed in the container terminated with an
  *       error.  The exit code of the program executed in the
- *       container is returned.  No change is made to the container
- *       argument.
+ *       container is returned.  The container argument has been set
+ *       to CONTAINER_TERMINATED.
  *   0 : The container is being rebooted, has been shut down or exited
  *       successfully.  The container argument has been set to either
  *       CONTAINER_TERMINATED or CONTAINER_REBOOTED.
@@ -2921,8 +2921,8 @@
  * error is indicated by a non-zero value.
  */
 static int wait_for_container(pid_t pid, ContainerStatus *container) {
-        int r;
         siginfo_t status;
+        int r;
 
         r = wait_for_terminate(pid, &status);
         if (r < 0) {
@@ -2931,51 +2931,40 @@
         }
 
         switch (status.si_code) {
+
         case CLD_EXITED:
-                r = status.si_status;
-                if (r == 0) {
-                        if (!arg_quiet)
-                                log_debug("Container %s exited successfully.",
-                                          arg_machine);
+                if (status.si_status == 0) {
+                        log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, "Container %s exited successfully.", arg_machine);
 
-                        *container = CONTAINER_TERMINATED;
-                } else {
-                        log_error("Container %s failed with error code %i.",
-                                  arg_machine, status.si_status);
-                }
-                break;
+                } else
+                        log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, "Container %s failed with error code %i.", arg_machine, status.si_status);
+
+                *container = CONTAINER_TERMINATED;
+                return status.si_status;
 
         case CLD_KILLED:
                 if (status.si_status == SIGINT) {
-                        if (!arg_quiet)
-                                log_info("Container %s has been shut down.",
-                                         arg_machine);
 
+                        log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, "Container %s has been shut down.", arg_machine);
                         *container = CONTAINER_TERMINATED;
-                        r = 0;
-                        break;
+                        return 0;
+
                 } else if (status.si_status == SIGHUP) {
-                        if (!arg_quiet)
-                                log_info("Container %s is being rebooted.",
-                                         arg_machine);
 
+                        log_full(arg_quiet ? LOG_DEBUG : LOG_INFO, "Container %s is being rebooted.", arg_machine);
                         *container = CONTAINER_REBOOTED;
-                        r = 0;
-                        break;
+                        return 0;
                 }
+
                 /* CLD_KILLED fallthrough */
 
         case CLD_DUMPED:
-                log_error("Container %s terminated by signal %s.",
-                          arg_machine, signal_to_string(status.si_status));
-                r = -1;
-                break;
+                log_error("Container %s terminated by signal %s.", arg_machine, signal_to_string(status.si_status));
+                return -EIO;
 
         default:
-                log_error("Container %s failed due to unknown reason.",
-                          arg_machine);
-                r = -1;
-                break;
+                log_error("Container %s failed due to unknown reason.", arg_machine);
+                return -EIO;
         }
 
         return r;
diff -urN systemd-216/src/python-systemd/_reader.c systemd-217/src/python-systemd/_reader.c
--- systemd-216/src/python-systemd/_reader.c	2014-08-01 09:46:39.310201101 -0700
+++ systemd-217/src/python-systemd/_reader.c	2014-10-17 04:49:07.965593679 -0700
@@ -313,7 +313,7 @@
              "Part of the context manager protocol.\n"
              "Closes the journal.\n");
 static PyObject* Reader___exit__(Reader *self, PyObject *args) {
-        return Reader_close(self, args);
+        return Reader_close(self, NULL);
 }
 
 PyDoc_STRVAR(Reader_next__doc__,
diff -urN systemd-216/src/resolve/resolved.c systemd-217/src/resolve/resolved.c
--- systemd-216/src/resolve/resolved.c	2014-11-03 09:35:21.489111575 -0800
+++ systemd-217/src/resolve/resolved.c	2014-10-23 08:13:15.777717921 -0700
@@ -22,6 +22,7 @@
 #include "sd-event.h"
 #include "sd-daemon.h"
 #include "mkdir.h"
+#include "label.h"
 #include "capability.h"
 
 #include "resolved-manager.h"
@@ -38,14 +39,20 @@
         log_parse_environment();
         log_open();
 
-        umask(0022);
-
         if (argc != 1) {
                 log_error("This program takes no arguments.");
                 r = -EINVAL;
                 goto finish;
         }
 
+        umask(0022);
+
+        r = mac_selinux_init(NULL);
+        if (r < 0) {
+                log_error("SELinux setup failed: %s", strerror(-r));
+                goto finish;
+        }
+
         r = get_user_creds(&user, &uid, &gid, NULL, NULL);
         if (r < 0) {
                 log_error("Cannot resolve user name %s: %s", user, strerror(-r));
diff -urN systemd-216/src/resolve/resolved-dns-scope.c systemd-217/src/resolve/resolved-dns-scope.c
--- systemd-216/src/resolve/resolved-dns-scope.c	2014-11-03 09:35:27.872175935 -0800
+++ systemd-217/src/resolve/resolved-dns-scope.c	2014-10-23 10:00:37.305180732 -0700
@@ -82,10 +82,10 @@
                 dns_transaction_free(t);
         }
 
-        while ((rr = hashmap_steal_first(s->conflict_queue)))
+        while ((rr = ordered_hashmap_steal_first(s->conflict_queue)))
                 dns_resource_record_unref(rr);
 
-        hashmap_free(s->conflict_queue);
+        ordered_hashmap_free(s->conflict_queue);
         sd_event_source_unref(s->conflict_event_source);
 
         dns_cache_flush(&s->cache);
@@ -682,7 +682,7 @@
                 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
                 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
 
-                rr = hashmap_steal_first(scope->conflict_queue);
+                rr = ordered_hashmap_steal_first(scope->conflict_queue);
                 if (!rr)
                         break;
 
@@ -709,7 +709,7 @@
 
         /* We don't send these queries immediately. Instead, we queue
          * them, and send them after some jitter delay. */
-        r = hashmap_ensure_allocated(&scope->conflict_queue, &dns_resource_key_hash_ops);
+        r = ordered_hashmap_ensure_allocated(&scope->conflict_queue, &dns_resource_key_hash_ops);
         if (r < 0) {
                 log_oom();
                 return r;
@@ -718,7 +718,7 @@
         /* We only place one RR per key in the conflict
          * messages, not all of them. That should be enough to
          * indicate where there might be a conflict */
-        r = hashmap_put(scope->conflict_queue, rr->key, rr);
+        r = ordered_hashmap_put(scope->conflict_queue, rr->key, rr);
         if (r == -EEXIST || r == 0)
                 return 0;
         if (r < 0) {
diff -urN systemd-216/src/resolve/resolved-dns-scope.h systemd-217/src/resolve/resolved-dns-scope.h
--- systemd-216/src/resolve/resolved-dns-scope.h	2014-08-13 16:01:43.877631023 -0700
+++ systemd-217/src/resolve/resolved-dns-scope.h	2014-10-23 10:00:37.305180732 -0700
@@ -55,7 +55,7 @@
         DnsCache cache;
         DnsZone zone;
 
-        Hashmap *conflict_queue;
+        OrderedHashmap *conflict_queue;
         sd_event_source *conflict_event_source;
 
         RateLimit ratelimit;
diff -urN systemd-216/src/resolve/resolved-dns-stream.c systemd-217/src/resolve/resolved-dns-stream.c
--- systemd-216/src/resolve/resolved-dns-stream.c	2014-11-03 09:35:21.818114892 -0800
+++ systemd-217/src/resolve/resolved-dns-stream.c	2014-10-22 07:52:00.510552676 -0700
@@ -157,7 +157,7 @@
          * device if the connection came from the local host since it
          * avoids the routing table in such a case. Let's unset the
          * interface index in such a case. */
-        if (s->ifindex > 0 && manager_ifindex_is_loopback(s->manager, s->ifindex) != 0)
+        if (s->ifindex == LOOPBACK_IFINDEX)
                 s->ifindex = 0;
 
         /* If we don't know the interface index still, we look for the
diff -urN systemd-216/src/resolve/resolved-manager.c systemd-217/src/resolve/resolved-manager.c
--- systemd-216/src/resolve/resolved-manager.c	2014-11-03 09:35:27.874175955 -0800
+++ systemd-217/src/resolve/resolved-manager.c	2014-10-22 07:43:01.920136799 -0700
@@ -34,6 +34,7 @@
 #include "socket-util.h"
 #include "af-list.h"
 #include "utf8.h"
+#include "fileio-label.h"
 
 #include "resolved-dns-domain.h"
 #include "resolved-conf.h"
@@ -720,12 +721,44 @@
         (*count) ++;
 }
 
+static int write_resolv_conf_contents(FILE *f, Set *dns, Set *domains) {
+        Iterator i;
+
+        fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
+              "# Third party programs must not access this file directly, but\n"
+              "# only through the symlink at /etc/resolv.conf. To manage\n"
+              "# resolv.conf(5) in a different way, replace the symlink by a\n"
+              "# static file or a different symlink.\n\n", f);
+
+        if (set_isempty(dns))
+                fputs("# No DNS servers known.\n", f);
+        else {
+                DnsServer *s;
+                unsigned count = 0;
+
+                SET_FOREACH(s, dns, i)
+                        write_resolv_conf_server(s, f, &count);
+        }
+
+        if (!set_isempty(domains)) {
+                unsigned length = 0, count = 0;
+                char *domain;
+
+                fputs("search", f);
+                SET_FOREACH(domain, domains, i)
+                        write_resolv_conf_search(domain, f, &count, &length);
+                fputs("\n", f);
+        }
+
+        return fflush_and_check(f);
+}
+
+
 int manager_write_resolv_conf(Manager *m) {
         static const char path[] = "/run/systemd/resolve/resolv.conf";
         _cleanup_free_ char *temp_path = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_set_free_ Set *dns = NULL, *domains = NULL;
-        unsigned count = 0;
         DnsServer *s;
         Iterator i;
         Link *l;
@@ -789,38 +822,13 @@
                 }
         }
 
-        r = fopen_temporary(path, &f, &temp_path);
+        r = fopen_temporary_label(path, path, &f, &temp_path);
         if (r < 0)
                 return r;
 
         fchmod(fileno(f), 0644);
 
-        fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
-              "# Third party programs must not access this file directly, but\n"
-              "# only through the symlink at /etc/resolv.conf. To manage\n"
-              "# resolv.conf(5) in a different way, replace the symlink by a\n"
-              "# static file or a different symlink.\n\n", f);
-
-        if (set_isempty(dns))
-                fputs("# No DNS servers known.\n", f);
-        else {
-                SET_FOREACH(s, dns, i)
-                        write_resolv_conf_server(s, f, &count);
-        }
-
-        if (!set_isempty(domains)) {
-                unsigned length = 0;
-                char *domain;
-
-                count = 0;
-
-                fputs("search", f);
-                SET_FOREACH(domain, domains, i)
-                        write_resolv_conf_search(domain, f, &count, &length);
-                fputs("\n", f);
-        }
-
-        r = fflush_and_check(f);
+        r = write_resolv_conf_contents(f, dns, domains);
         if (r < 0)
                 goto fail;
 
@@ -952,7 +960,7 @@
          * device if the packet came from the local host since it
          * avoids the routing table in such a case. Let's unset the
          * interface index in such a case. */
-        if (p->ifindex > 0 && manager_ifindex_is_loopback(m, p->ifindex) != 0)
+        if (p->ifindex == LOOPBACK_IFINDEX)
                 p->ifindex = 0;
 
         /* If we don't know the interface index still, we look for the
@@ -1687,26 +1695,6 @@
         return r;
 }
 
-/* lo having ifindex 1 is hardcoded in the kernel */
-#define LOOPBACK_IFINDEX 1
-
-int manager_ifindex_is_loopback(Manager *m, int ifindex) {
-        Link *l;
-        assert(m);
-
-        if (ifindex <= 0)
-                return -EINVAL;
-
-        l = hashmap_get(m->links, INT_TO_PTR(ifindex));
-        if (!l)
-                /* in case we don't yet track the link, rely on the hardcoded value */
-                return ifindex == LOOPBACK_IFINDEX;
-        else if (l->flags & IFF_LOOPBACK)
-                return 1;
-
-        return 0;
-}
-
 int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
         LinkAddress *a;
 
diff -urN systemd-216/src/resolve/resolved-manager.h systemd-217/src/resolve/resolved-manager.h
--- systemd-216/src/resolve/resolved-manager.h	2014-08-13 05:09:51.598813981 -0700
+++ systemd-217/src/resolve/resolved-manager.h	2014-10-22 07:40:12.404293996 -0700
@@ -139,7 +139,6 @@
 int manager_llmnr_ipv4_tcp_fd(Manager *m);
 int manager_llmnr_ipv6_tcp_fd(Manager *m);
 
-int manager_ifindex_is_loopback(Manager *m, int ifindex);
 int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr);
 LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr);
 
diff -urN systemd-216/src/shared/apparmor-util.c systemd-217/src/shared/apparmor-util.c
--- systemd-216/src/shared/apparmor-util.c	2014-03-18 10:05:50.205378174 -0700
+++ systemd-217/src/shared/apparmor-util.c	2014-10-23 08:22:34.437843127 -0700
@@ -25,17 +25,16 @@
 #include "fileio.h"
 #include "apparmor-util.h"
 
-static int use_apparmor_cached = -1;
+bool mac_apparmor_use(void) {
+        static int cached_use = -1;
 
-bool use_apparmor(void) {
-
-        if (use_apparmor_cached < 0) {
+        if (cached_use < 0) {
                 _cleanup_free_ char *p = NULL;
 
-                use_apparmor_cached =
+                cached_use =
                         read_one_line_file("/sys/module/apparmor/parameters/enabled", &p) >= 0 &&
                         parse_boolean(p) > 0;
         }
 
-        return use_apparmor_cached;
+        return cached_use;
 }
diff -urN systemd-216/src/shared/apparmor-util.h systemd-217/src/shared/apparmor-util.h
--- systemd-216/src/shared/apparmor-util.h	2014-02-12 18:42:33.994684310 -0800
+++ systemd-217/src/shared/apparmor-util.h	2014-10-23 08:22:48.855805199 -0700
@@ -23,4 +23,4 @@
 
 #include <stdbool.h>
 
-bool use_apparmor(void);
+bool mac_apparmor_use(void);
diff -urN systemd-216/src/shared/calendarspec.c systemd-217/src/shared/calendarspec.c
--- systemd-216/src/shared/calendarspec.c	2014-03-24 19:57:13.670621055 -0700
+++ systemd-217/src/shared/calendarspec.c	2014-10-27 10:09:26.683861816 -0700
@@ -35,7 +35,9 @@
 }
 
 void calendar_spec_free(CalendarSpec *c) {
-        assert(c);
+
+        if (!c)
+                return;
 
         free_chain(c->year);
         free_chain(c->month);
@@ -472,7 +474,7 @@
 
         cc->value = value;
         cc->repeat = 0;
-        cc->next = NULL;
+        cc->next = *c;
 
         *c = cc;
 
@@ -653,7 +655,12 @@
         if (!c)
                 return -ENOMEM;
 
-        if (strcaseeq(p, "hourly")) {
+        if (strcaseeq(p, "minutely")) {
+                r = const_chain(0, &c->second);
+                if (r < 0)
+                        goto fail;
+
+        } else if (strcaseeq(p, "hourly")) {
                 r = const_chain(0, &c->minute);
                 if (r < 0)
                         goto fail;
@@ -686,7 +693,10 @@
                 if (r < 0)
                         goto fail;
 
-        } else if (strcaseeq(p, "anually") || strcaseeq(p, "yearly")) {
+        } else if (strcaseeq(p, "annually") ||
+                   strcaseeq(p, "yearly") ||
+                   strcaseeq(p, "anually") /* backwards compatibility */ ) {
+
                 r = const_chain(1, &c->month);
                 if (r < 0)
                         goto fail;
@@ -710,6 +720,57 @@
                 r = const_chain(0, &c->hour);
                 if (r < 0)
                         goto fail;
+                r = const_chain(0, &c->minute);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->second);
+                if (r < 0)
+                        goto fail;
+
+        } else if (strcaseeq(p, "quarterly")) {
+
+                r = const_chain(1, &c->month);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(4, &c->month);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(7, &c->month);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(10, &c->month);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(1, &c->day);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->hour);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->minute);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->second);
+                if (r < 0)
+                        goto fail;
+
+        } else if (strcaseeq(p, "biannually") ||
+                   strcaseeq(p, "bi-annually") ||
+                   strcaseeq(p, "semiannually") ||
+                   strcaseeq(p, "semi-annually")) {
+
+                r = const_chain(1, &c->month);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(7, &c->month);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(1, &c->day);
+                if (r < 0)
+                        goto fail;
+                r = const_chain(0, &c->hour);
+                if (r < 0)
+                        goto fail;
                 r = const_chain(0, &c->minute);
                 if (r < 0)
                         goto fail;
diff -urN systemd-216/src/shared/dev-setup.c systemd-217/src/shared/dev-setup.c
--- systemd-216/src/shared/dev-setup.c	2014-03-19 08:25:11.505470330 -0700
+++ systemd-217/src/shared/dev-setup.c	2014-10-23 12:36:56.911756034 -0700
@@ -32,24 +32,6 @@
 #include "util.h"
 #include "label.h"
 
-static int symlink_and_label(const char *old_path, const char *new_path) {
-        int r;
-
-        assert(old_path);
-        assert(new_path);
-
-        r = label_context_set(new_path, S_IFLNK);
-        if (r < 0)
-                return r;
-
-        if (symlink(old_path, new_path) < 0)
-                r = -errno;
-
-        label_context_clear();
-
-        return r;
-}
-
 int dev_setup(const char *prefix) {
         const char *j, *k;
 
@@ -75,9 +57,9 @@
                         if (!link_name)
                                 return -ENOMEM;
 
-                        symlink_and_label(j, link_name);
+                        symlink_label(j, link_name);
                 } else
-                        symlink_and_label(j, k);
+                        symlink_label(j, k);
         }
 
         return 0;
diff -urN systemd-216/src/shared/env-util.c systemd-217/src/shared/env-util.c
--- systemd-216/src/shared/env-util.c	2014-07-07 06:25:55.688514066 -0700
+++ systemd-217/src/shared/env-util.c	2014-10-20 10:23:13.444878955 -0700
@@ -28,6 +28,7 @@
 #include "util.h"
 #include "env-util.h"
 #include "def.h"
+#include "unit.h"
 
 #define VALID_CHARS_ENV_NAME                    \
         DIGITS LETTERS                          \
@@ -414,7 +415,7 @@
         return strv_env_get_n(l, name, strlen(name));
 }
 
-char **strv_env_clean_log(char **e, const char *message) {
+char **strv_env_clean_log(char **e, const char *unit_id, const char *message) {
         char **p, **q;
         int k = 0;
 
@@ -424,7 +425,7 @@
 
                 if (!env_assignment_is_valid(*p)) {
                         if (message)
-                                log_error("Ignoring invalid environment '%s': %s", *p, message);
+                                log_error_unit(unit_id, "Ignoring invalid environment '%s': %s", *p, message);
                         free(*p);
                         continue;
                 }
@@ -451,5 +452,5 @@
 }
 
 char **strv_env_clean(char **e) {
-        return strv_env_clean_log(e, NULL);
+        return strv_env_clean_log(e, NULL, NULL);
 }
diff -urN systemd-216/src/shared/env-util.h systemd-217/src/shared/env-util.h
--- systemd-216/src/shared/env-util.h	2014-02-12 18:42:34.389682715 -0800
+++ systemd-217/src/shared/env-util.h	2014-10-20 10:23:13.444878955 -0700
@@ -30,7 +30,7 @@
 
 bool strv_env_is_valid(char **e);
 char **strv_env_clean(char **l);
-char **strv_env_clean_log(char **e, const char *message);
+char **strv_env_clean_log(char **e, const char *unit_id, const char *message);
 
 bool strv_env_name_or_assignment_is_valid(char **l);
 
diff -urN systemd-216/src/shared/fileio-label.c systemd-217/src/shared/fileio-label.c
--- systemd-216/src/shared/fileio-label.c	2014-11-03 09:35:34.231240053 -0800
+++ systemd-217/src/shared/fileio-label.c	2014-10-23 12:36:56.810756232 -0700
@@ -30,13 +30,13 @@
 int write_string_file_atomic_label(const char *fn, const char *line) {
         int r;
 
-        r = label_context_set(fn, S_IFREG);
+        r = mac_selinux_create_file_prepare(fn, S_IFREG);
         if (r < 0)
                 return r;
 
         r = write_string_file_atomic(fn, line);
 
-        label_context_clear();
+        mac_selinux_create_file_clear();
 
         return r;
 }
@@ -44,13 +44,13 @@
 int write_env_file_label(const char *fname, char **l) {
         int r;
 
-        r = label_context_set(fname, S_IFREG);
+        r = mac_selinux_create_file_prepare(fname, S_IFREG);
         if (r < 0)
                 return r;
 
         r = write_env_file(fname, l);
 
-        label_context_clear();
+        mac_selinux_create_file_clear();
 
         return r;
 }
@@ -59,13 +59,13 @@
                           const char *path, FILE **f, char **temp_path) {
         int r;
 
-        r = label_context_set(target, S_IFREG);
+        r = mac_selinux_create_file_prepare(target, S_IFREG);
         if (r < 0)
                 return r;
 
         r = fopen_temporary(path, f, temp_path);
 
-        label_context_clear();
+        mac_selinux_create_file_clear();
 
         return r;
 }
diff -urN systemd-216/src/shared/hashmap.c systemd-217/src/shared/hashmap.c
--- systemd-216/src/shared/hashmap.c	2014-11-03 09:35:28.016177387 -0800
+++ systemd-217/src/shared/hashmap.c	2014-10-23 10:00:37.306180793 -0700
@@ -28,6 +28,7 @@
 #include "hashmap.h"
 #include "macro.h"
 #include "siphash24.h"
+#include "mempool.h"
 
 #define INITIAL_N_BUCKETS 31
 
@@ -50,82 +51,21 @@
         bool from_pool:1;
 };
 
-struct pool {
-        struct pool *next;
-        unsigned n_tiles;
-        unsigned n_used;
+struct hashmap_tile {
+        Hashmap h;
+        struct hashmap_entry *initial_buckets[INITIAL_N_BUCKETS];
 };
 
-static struct pool *first_hashmap_pool = NULL;
-static void *first_hashmap_tile = NULL;
-
-static struct pool *first_entry_pool = NULL;
-static void *first_entry_tile = NULL;
-
-static void* allocate_tile(struct pool **first_pool, void **first_tile, size_t tile_size, unsigned at_least) {
-        unsigned i;
-
-        /* When a tile is released we add it to the list and simply
-         * place the next pointer at its offset 0. */
-
-        assert(tile_size >= sizeof(void*));
-        assert(at_least > 0);
-
-        if (*first_tile) {
-                void *r;
-
-                r = *first_tile;
-                *first_tile = * (void**) (*first_tile);
-                return r;
-        }
-
-        if (_unlikely_(!*first_pool) || _unlikely_((*first_pool)->n_used >= (*first_pool)->n_tiles)) {
-                unsigned n;
-                size_t size;
-                struct pool *p;
-
-                n = *first_pool ? (*first_pool)->n_tiles : 0;
-                n = MAX(at_least, n * 2);
-                size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*tile_size);
-                n = (size - ALIGN(sizeof(struct pool))) / tile_size;
-
-                p = malloc(size);
-                if (!p)
-                        return NULL;
-
-                p->next = *first_pool;
-                p->n_tiles = n;
-                p->n_used = 0;
-
-                *first_pool = p;
-        }
-
-        i = (*first_pool)->n_used++;
-
-        return ((uint8_t*) (*first_pool)) + ALIGN(sizeof(struct pool)) + i*tile_size;
-}
-
-static void deallocate_tile(void **first_tile, void *p) {
-        * (void**) p = *first_tile;
-        *first_tile = p;
-}
+static DEFINE_MEMPOOL(hashmap_pool, struct hashmap_tile, 8);
+static DEFINE_MEMPOOL(hashmap_entry_pool, struct hashmap_entry, 64);
 
 #ifdef VALGRIND
 
-static void drop_pool(struct pool *p) {
-        while (p) {
-                struct pool *n;
-                n = p->next;
-                free(p);
-                p = n;
-        }
-}
-
-__attribute__((destructor)) static void cleanup_pool(void) {
+__attribute__((destructor)) static void cleanup_pools(void) {
         /* Be nice to valgrind */
 
-        drop_pool(first_hashmap_pool);
-        drop_pool(first_entry_pool);
+        mempool_drop(&hashmap_entry_pool);
+        mempool_drop(&hashmap_pool);
 }
 
 #endif
@@ -223,33 +163,32 @@
 
 Hashmap *hashmap_new(const struct hash_ops *hash_ops) {
         bool b;
+        struct hashmap_tile *ht;
         Hashmap *h;
-        size_t size;
 
         b = is_main_thread();
 
-        size = ALIGN(sizeof(Hashmap)) + INITIAL_N_BUCKETS * sizeof(struct hashmap_entry*);
-
         if (b) {
-                h = allocate_tile(&first_hashmap_pool, &first_hashmap_tile, size, 8);
-                if (!h)
+                ht = mempool_alloc_tile(&hashmap_pool);
+                if (!ht)
                         return NULL;
 
-                memzero(h, size);
+                memzero(ht, sizeof(struct hashmap_tile));
         } else {
-                h = malloc0(size);
+                ht = malloc0(sizeof(struct hashmap_tile));
 
-                if (!h)
+                if (!ht)
                         return NULL;
         }
 
+        h = &ht->h;
         h->hash_ops = hash_ops ? hash_ops : &trivial_hash_ops;
 
         h->n_buckets = INITIAL_N_BUCKETS;
         h->n_entries = 0;
         h->iterate_list_head = h->iterate_list_tail = NULL;
 
-        h->buckets = (struct hashmap_entry**) ((uint8_t*) h + ALIGN(sizeof(Hashmap)));
+        h->buckets = ht->initial_buckets;
 
         h->from_pool = b;
 
@@ -339,7 +278,7 @@
         unlink_entry(h, e, hash);
 
         if (h->from_pool)
-                deallocate_tile(&first_entry_tile, e);
+                mempool_free_tile(&hashmap_entry_pool, e);
         else
                 free(e);
 }
@@ -357,7 +296,7 @@
                 free(h->buckets);
 
         if (h->from_pool)
-                deallocate_tile(&first_hashmap_tile, h);
+                mempool_free_tile(&hashmap_pool, container_of(h, struct hashmap_tile, h));
         else
                 free(h);
 }
@@ -430,23 +369,31 @@
         return NULL;
 }
 
-static bool resize_buckets(Hashmap *h) {
+static int resize_buckets(Hashmap *h, unsigned entries_add) {
         struct hashmap_entry **n, *i;
-        unsigned m;
+        unsigned m, new_n_entries, new_n_buckets;
         uint8_t nkey[HASH_KEY_SIZE];
 
         assert(h);
 
-        if (_likely_(h->n_entries*4 < h->n_buckets*3))
-                return false;
+        new_n_entries = h->n_entries + entries_add;
+
+        /* overflow? */
+        if (_unlikely_(new_n_entries < entries_add || new_n_entries > UINT_MAX / 4))
+                return -ENOMEM;
+
+        new_n_buckets = new_n_entries * 4 / 3;
+
+        if (_likely_(new_n_buckets <= h->n_buckets))
+                return 0;
 
-        /* Increase by four */
-        m = (h->n_entries+1)*4-1;
+        /* Increase by four at least */
+        m = MAX((h->n_entries+1)*4-1, new_n_buckets);
 
         /* If we hit OOM we simply risk packed hashmaps... */
         n = new0(struct hashmap_entry*, m);
         if (!n)
-                return false;
+                return -ENOMEM;
 
         /* Let's use a different randomized hash key for the
          * extension, so that people cannot guess what we are using
@@ -485,7 +432,7 @@
 
         memcpy(h->hash_key, nkey, HASH_KEY_SIZE);
 
-        return true;
+        return 1;
 }
 
 static int __hashmap_put(Hashmap *h, const void *key, void *value, unsigned hash) {
@@ -493,11 +440,11 @@
 
         struct hashmap_entry *e;
 
-        if (resize_buckets(h))
+        if (resize_buckets(h, 1) > 0)
                 hash = bucket_hash(h, key);
 
         if (h->from_pool)
-                e = allocate_tile(&first_entry_pool, &first_entry_tile, sizeof(struct hashmap_entry), 64U);
+                e = mempool_alloc_tile(&hashmap_entry_pool);
         else
                 e = new(struct hashmap_entry, 1);
 
@@ -856,16 +803,28 @@
         return 0;
 }
 
-void hashmap_move(Hashmap *h, Hashmap *other) {
+int hashmap_reserve(Hashmap *h, unsigned entries_add) {
+        int r;
+
+        assert(h);
+
+        r = resize_buckets(h, entries_add);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int hashmap_move(Hashmap *h, Hashmap *other) {
         struct hashmap_entry *e, *n;
 
         assert(h);
 
         /* The same as hashmap_merge(), but every new item from other
-         * is moved to h. This function is guaranteed to succeed. */
+         * is moved to h. */
 
         if (!other)
-                return;
+                return 0;
 
         for (e = other->iterate_list_head; e; e = n) {
                 unsigned h_hash, other_hash;
@@ -880,21 +839,23 @@
                 unlink_entry(other, e, other_hash);
                 link_entry(h, e, h_hash);
         }
+
+        return 0;
 }
 
 int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) {
         unsigned h_hash, other_hash;
         struct hashmap_entry *e;
 
-        if (!other)
-                return 0;
-
         assert(h);
 
         h_hash = bucket_hash(h, key);
         if (hash_scan(h, h_hash, key))
                 return -EEXIST;
 
+        if (!other)
+                return -ENOENT;
+
         other_hash = bucket_hash(other, key);
         e = hash_scan(other, other_hash, key);
         if (!e)
@@ -945,7 +906,6 @@
         unsigned hash;
         struct hashmap_entry *e;
 
-        assert(h);
         assert(key);
 
         if (!h)
diff -urN systemd-216/src/shared/hashmap.h systemd-217/src/shared/hashmap.h
--- systemd-216/src/shared/hashmap.h	2014-11-03 09:35:27.951176732 -0800
+++ systemd-217/src/shared/hashmap.h	2014-10-23 10:00:37.306180793 -0700
@@ -34,6 +34,7 @@
 #define HASH_KEY_SIZE 16
 
 typedef struct Hashmap Hashmap;
+typedef struct OrderedHashmap OrderedHashmap;
 typedef struct _IteratorStruct _IteratorStruct;
 typedef _IteratorStruct* Iterator;
 
@@ -82,56 +83,175 @@
 #endif
 
 Hashmap *hashmap_new(const struct hash_ops *hash_ops);
+static inline OrderedHashmap *ordered_hashmap_new(const struct hash_ops *hash_ops) {
+        return (OrderedHashmap*) hashmap_new(hash_ops);
+}
 void hashmap_free(Hashmap *h);
+static inline void ordered_hashmap_free(OrderedHashmap *h) {
+        hashmap_free((Hashmap*) h);
+}
 void hashmap_free_free(Hashmap *h);
+static inline void ordered_hashmap_free_free(OrderedHashmap *h) {
+        hashmap_free_free((Hashmap*) h);
+}
 void hashmap_free_free_free(Hashmap *h);
+static inline void ordered_hashmap_free_free_free(OrderedHashmap *h) {
+        hashmap_free_free_free((Hashmap*) h);
+}
 Hashmap *hashmap_copy(Hashmap *h);
+static inline OrderedHashmap *ordered_hashmap_copy(OrderedHashmap *h) {
+        return (OrderedHashmap*) hashmap_copy((Hashmap*) h);
+}
 int hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops);
+static inline int ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops) {
+        return hashmap_ensure_allocated((Hashmap**) h, hash_ops);
+}
 
 int hashmap_put(Hashmap *h, const void *key, void *value);
+static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void *value) {
+        return hashmap_put((Hashmap*) h, key, value);
+}
 int hashmap_update(Hashmap *h, const void *key, void *value);
+static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) {
+        return hashmap_update((Hashmap*) h, key, value);
+}
 int hashmap_replace(Hashmap *h, const void *key, void *value);
+static inline int ordered_hashmap_replace(OrderedHashmap *h, const void *key, void *value) {
+        return hashmap_replace((Hashmap*) h, key, value);
+}
 void *hashmap_get(Hashmap *h, const void *key);
+static inline void *ordered_hashmap_get(OrderedHashmap *h, const void *key) {
+        return hashmap_get((Hashmap*) h, key);
+}
 void *hashmap_get2(Hashmap *h, const void *key, void **rkey);
+static inline void *ordered_hashmap_get2(OrderedHashmap *h, const void *key, void **rkey) {
+        return hashmap_get2((Hashmap*) h, key, rkey);
+}
 bool hashmap_contains(Hashmap *h, const void *key);
+static inline bool ordered_hashmap_contains(OrderedHashmap *h, const void *key) {
+        return hashmap_contains((Hashmap*) h, key);
+}
 void *hashmap_remove(Hashmap *h, const void *key);
+static inline void *ordered_hashmap_remove(OrderedHashmap *h, const void *key) {
+        return hashmap_remove((Hashmap*) h, key);
+}
 void *hashmap_remove2(Hashmap *h, const void *key, void **rkey);
+static inline void *ordered_hashmap_remove2(OrderedHashmap *h, const void *key, void **rkey) {
+        return hashmap_remove2((Hashmap*) h, key, rkey);
+}
 void *hashmap_remove_value(Hashmap *h, const void *key, void *value);
+static inline void *ordered_hashmap_remove_value(OrderedHashmap *h, const void *key, void *value) {
+        return hashmap_remove_value((Hashmap*) h, key, value);
+}
 int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value);
+static inline int ordered_hashmap_remove_and_put(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) {
+        return hashmap_remove_and_put((Hashmap*) h, old_key, new_key, value);
+}
 int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value);
+static inline int ordered_hashmap_remove_and_replace(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) {
+        return hashmap_remove_and_replace((Hashmap*) h, old_key, new_key, value);
+}
 
 int hashmap_merge(Hashmap *h, Hashmap *other);
-void hashmap_move(Hashmap *h, Hashmap *other);
+static inline int ordered_hashmap_merge(OrderedHashmap *h, OrderedHashmap *other) {
+        return hashmap_merge((Hashmap*) h, (Hashmap*) other);
+}
+int hashmap_reserve(Hashmap *h, unsigned entries_add);
+static inline int ordered_hashmap_reserve(OrderedHashmap *h, unsigned entries_add) {
+        return hashmap_reserve((Hashmap*) h, entries_add);
+}
+int hashmap_move(Hashmap *h, Hashmap *other);
+static inline int ordered_hashmap_move(OrderedHashmap *h, OrderedHashmap *other) {
+        return hashmap_move((Hashmap*) h, (Hashmap*) other);
+}
 int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key);
+static inline int ordered_hashmap_move_one(OrderedHashmap *h, OrderedHashmap *other, const void *key) {
+        return hashmap_move_one((Hashmap*) h, (Hashmap*) other, key);
+}
 
 unsigned hashmap_size(Hashmap *h) _pure_;
+static inline unsigned ordered_hashmap_size(OrderedHashmap *h) {
+        return hashmap_size((Hashmap*) h);
+}
 bool hashmap_isempty(Hashmap *h) _pure_;
+static inline bool ordered_hashmap_isempty(OrderedHashmap *h) {
+        return hashmap_isempty((Hashmap*) h);
+}
 unsigned hashmap_buckets(Hashmap *h) _pure_;
+static inline unsigned ordered_hashmap_buckets(OrderedHashmap *h) {
+        return hashmap_buckets((Hashmap*) h);
+}
 
 void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key);
+static inline void *ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, const void **key) {
+        return hashmap_iterate((Hashmap*) h, i, key);
+}
 
 void hashmap_clear(Hashmap *h);
+static inline void ordered_hashmap_clear(OrderedHashmap *h) {
+        hashmap_clear((Hashmap*) h);
+}
 void hashmap_clear_free(Hashmap *h);
+static inline void ordered_hashmap_clear_free(OrderedHashmap *h) {
+        hashmap_clear_free((Hashmap*) h);
+}
 void hashmap_clear_free_free(Hashmap *h);
+static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) {
+        hashmap_clear_free_free((Hashmap*) h);
+}
 
 void *hashmap_steal_first(Hashmap *h);
+static inline void *ordered_hashmap_steal_first(OrderedHashmap *h) {
+        return hashmap_steal_first((Hashmap*) h);
+}
 void *hashmap_steal_first_key(Hashmap *h);
+static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) {
+        return hashmap_steal_first_key((Hashmap*) h);
+}
 void *hashmap_first(Hashmap *h) _pure_;
+static inline void *ordered_hashmap_first(OrderedHashmap *h) {
+        return hashmap_first((Hashmap*) h);
+}
 void *hashmap_first_key(Hashmap *h) _pure_;
+static inline void *ordered_hashmap_first_key(OrderedHashmap *h) {
+        return hashmap_first_key((Hashmap*) h);
+}
 
 void *hashmap_next(Hashmap *h, const void *key);
+static inline void *ordered_hashmap_next(OrderedHashmap *h, const void *key) {
+        return hashmap_next((Hashmap*) h, key);
+}
 
 char **hashmap_get_strv(Hashmap *h);
+static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) {
+        return hashmap_get_strv((Hashmap*) h);
+}
 
 #define HASHMAP_FOREACH(e, h, i) \
         for ((i) = ITERATOR_FIRST, (e) = hashmap_iterate((h), &(i), NULL); (e); (e) = hashmap_iterate((h), &(i), NULL))
 
+#define ORDERED_HASHMAP_FOREACH(e, h, i) \
+        for ((i) = ITERATOR_FIRST, (e) = ordered_hashmap_iterate((h), &(i), NULL); \
+             (e); \
+             (e) = ordered_hashmap_iterate((h), &(i), NULL))
+
 #define HASHMAP_FOREACH_KEY(e, k, h, i) \
         for ((i) = ITERATOR_FIRST, (e) = hashmap_iterate((h), &(i), (const void**) &(k)); (e); (e) = hashmap_iterate((h), &(i), (const void**) &(k)))
 
+#define ORDERED_HASHMAP_FOREACH_KEY(e, k, h, i) \
+        for ((i) = ITERATOR_FIRST, (e) = ordered_hashmap_iterate((h), &(i), (const void**) &(k)); \
+             (e); \
+             (e) = ordered_hashmap_iterate((h), &(i), (const void**) &(k)))
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free);
+DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free);
+DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free);
+DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_free);
 #define _cleanup_hashmap_free_ _cleanup_(hashmap_freep)
 #define _cleanup_hashmap_free_free_ _cleanup_(hashmap_free_freep)
 #define _cleanup_hashmap_free_free_free_ _cleanup_(hashmap_free_free_freep)
+#define _cleanup_ordered_hashmap_free_ _cleanup_(ordered_hashmap_freep)
+#define _cleanup_ordered_hashmap_free_free_ _cleanup_(ordered_hashmap_free_freep)
+#define _cleanup_ordered_hashmap_free_free_free_ _cleanup_(ordered_hashmap_free_free_freep)
diff -urN systemd-216/src/shared/in-addr-util.c systemd-217/src/shared/in-addr-util.c
--- systemd-216/src/shared/in-addr-util.c	2014-08-11 13:18:21.479307964 -0700
+++ systemd-217/src/shared/in-addr-util.c	2014-10-27 10:09:26.607862012 -0700
@@ -248,3 +248,46 @@
 
         return 32 - u32ctz(be32toh(addr->s_addr));
 }
+
+int in_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen) {
+        uint32_t address;
+
+        assert(addr);
+        assert(addr->s_addr != INADDR_ANY);
+        assert(prefixlen);
+
+        address = be32toh(addr->s_addr);
+
+        if ((address >> 31) == 0x0)
+                /* class A, leading bits: 0 */
+                *prefixlen = 8;
+        else if ((address >> 30) == 0x2)
+                /* class B, leading bits 10 */
+                *prefixlen = 16;
+        else if ((address >> 29) == 0x6)
+                /* class C, leading bits 110 */
+                *prefixlen = 24;
+        else
+                /* class D or E, no default prefixlen */
+                return -ERANGE;
+
+        return 0;
+}
+
+int in_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask) {
+        unsigned char prefixlen;
+        int r;
+
+        assert(addr);
+        assert(mask);
+
+        r = in_addr_default_prefixlen(addr, &prefixlen);
+        if (r < 0)
+                return r;
+
+        assert(prefixlen > 0 && prefixlen < 32);
+
+        mask->s_addr = htobe32((0xffffffff << (32 - prefixlen)) & 0xffffffff);
+
+        return 0;
+}
diff -urN systemd-216/src/shared/in-addr-util.h systemd-217/src/shared/in-addr-util.h
--- systemd-216/src/shared/in-addr-util.h	2014-08-11 13:18:21.511308310 -0700
+++ systemd-217/src/shared/in-addr-util.h	2014-10-27 10:09:26.607862012 -0700
@@ -40,6 +40,8 @@
 int in_addr_from_string(int family, const char *s, union in_addr_union *ret);
 int in_addr_from_string_auto(const char *s, int *family, union in_addr_union *ret);
 unsigned in_addr_netmask_to_prefixlen(const struct in_addr *addr);
+int in_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen);
+int in_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask);
 
 static inline size_t FAMILY_ADDRESS_SIZE(int family) {
         assert(family == AF_INET || family == AF_INET6);
diff -urN systemd-216/src/shared/install.c systemd-217/src/shared/install.c
--- systemd-216/src/shared/install.c	2014-11-03 09:35:36.032258213 -0800
+++ systemd-217/src/shared/install.c	2014-11-03 09:33:48.906178061 -0800
@@ -41,8 +41,8 @@
 #include "special.h"
 
 typedef struct {
-        Hashmap *will_install;
-        Hashmap *have_installed;
+        OrderedHashmap *will_install;
+        OrderedHashmap *have_installed;
 } InstallContext;
 
 static int in_search_path(const char *path, char **search) {
@@ -844,16 +844,16 @@
         free(i);
 }
 
-static void install_info_hashmap_free(Hashmap *m) {
+static void install_info_hashmap_free(OrderedHashmap *m) {
         InstallInfo *i;
 
         if (!m)
                 return;
 
-        while ((i = hashmap_steal_first(m)))
+        while ((i = ordered_hashmap_steal_first(m)))
                 install_info_free(i);
 
-        hashmap_free(m);
+        ordered_hashmap_free(m);
 }
 
 static void install_context_done(InstallContext *c) {
@@ -881,11 +881,11 @@
         if (!unit_name_is_valid(name, TEMPLATE_VALID))
                 return -EINVAL;
 
-        if (hashmap_get(c->have_installed, name) ||
-            hashmap_get(c->will_install, name))
+        if (ordered_hashmap_get(c->have_installed, name) ||
+            ordered_hashmap_get(c->will_install, name))
                 return 0;
 
-        r = hashmap_ensure_allocated(&c->will_install, &string_hash_ops);
+        r = ordered_hashmap_ensure_allocated(&c->will_install, &string_hash_ops);
         if (r < 0)
                 return r;
 
@@ -907,7 +907,7 @@
                 }
         }
 
-        r = hashmap_put(c->will_install, i->name, i);
+        r = ordered_hashmap_put(c->will_install, i->name, i);
         if (r < 0)
                 goto fail;
 
@@ -1180,7 +1180,7 @@
         if (r < 0)
                 return r;
 
-        assert_se(i = hashmap_first(c.will_install));
+        assert_se(i = ordered_hashmap_first(c.will_install));
 
         r = unit_file_search(&c, i, paths, root_dir, allow_symlink, true);
 
@@ -1395,19 +1395,25 @@
                 unsigned *n_changes) {
 
         InstallInfo *i;
-        int r = 0, q;
+        int r, q;
 
         assert(c);
         assert(paths);
         assert(config_path);
 
-        while ((i = hashmap_first(c->will_install))) {
+        if (!ordered_hashmap_isempty(c->will_install)) {
+                r = ordered_hashmap_ensure_allocated(&c->have_installed, &string_hash_ops);
+                if (r < 0)
+                        return r;
 
-                q = hashmap_ensure_allocated(&c->have_installed, &string_hash_ops);
-                if (q < 0)
-                        return q;
+                r = ordered_hashmap_reserve(c->have_installed, ordered_hashmap_size(c->will_install));
+                if (r < 0)
+                        return r;
+        }
 
-                assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
+        r = 0;
+        while ((i = ordered_hashmap_first(c->will_install))) {
+                assert_se(ordered_hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
 
                 q = unit_file_search(c, i, paths, root_dir, false, true);
                 if (q < 0) {
@@ -1434,7 +1440,7 @@
                 const char *root_dir) {
 
         InstallInfo *i;
-        int r = 0, q;
+        int r, q;
 
         assert(c);
         assert(paths);
@@ -1442,13 +1448,19 @@
 
         /* Marks all items for removal */
 
-        while ((i = hashmap_first(c->will_install))) {
+        if (!ordered_hashmap_isempty(c->will_install)) {
+                r = ordered_hashmap_ensure_allocated(&c->have_installed, &string_hash_ops);
+                if (r < 0)
+                        return r;
 
-                q = hashmap_ensure_allocated(&c->have_installed, &string_hash_ops);
-                if (q < 0)
-                        return q;
+                r = ordered_hashmap_reserve(c->have_installed, ordered_hashmap_size(c->will_install));
+                if (r < 0)
+                        return r;
+        }
 
-                assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
+        r = 0;
+        while ((i = ordered_hashmap_first(c->will_install))) {
+                assert_se(ordered_hashmap_move_one(c->have_installed, c->will_install, i->name) == 0);
 
                 q = unit_file_search(c, i, paths, root_dir, false, true);
                 if (q == -ENOENT) {
@@ -1544,12 +1556,18 @@
                         return r;
         }
 
-        while ((info = hashmap_first(c.will_install))) {
-                r = hashmap_ensure_allocated(&c.have_installed, &string_hash_ops);
+        if (!ordered_hashmap_isempty(c.will_install)) {
+                r = ordered_hashmap_ensure_allocated(&c.have_installed, &string_hash_ops);
                 if (r < 0)
                         return r;
 
-                assert_se(hashmap_move_one(c.have_installed, c.will_install, info->name) == 0);
+                r = ordered_hashmap_reserve(c.have_installed, ordered_hashmap_size(c.will_install));
+                if (r < 0)
+                        return r;
+        }
+
+        while ((info = ordered_hashmap_first(c.will_install))) {
+                assert_se(ordered_hashmap_move_one(c.have_installed, c.will_install, info->name) == 0);
 
                 r = unit_file_search(&c, info, &paths, root_dir, false, false);
                 if (r < 0)
@@ -1602,12 +1620,10 @@
         STRV_FOREACH(i, files) {
                 UnitFileState state;
 
+                /* We only want to know if this unit is masked, so we ignore
+                 * errors from unit_file_get_state, deferring other checks.
+                 * This allows templated units to be enabled on the fly. */
                 state = unit_file_get_state(scope, root_dir, *i);
-                if (state < 0) {
-                        log_error("Failed to get unit file state for %s: %s", *i, strerror(-state));
-                        return state;
-                }
-
                 if (state == UNIT_FILE_MASKED || state == UNIT_FILE_MASKED_RUNTIME) {
                         log_error("Failed to enable unit: Unit %s is masked", *i);
                         return -ENOTSUP;
@@ -1661,7 +1677,7 @@
         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, files);
-        if (r == 0)
+        if (r >= 0)
                 r = q;
 
         return r;
@@ -1720,7 +1736,7 @@
         if (r < 0)
                 return r;
 
-        assert_se(i = hashmap_first(c.will_install));
+        assert_se(i = ordered_hashmap_first(c.will_install));
 
         r = unit_file_search(&c, i, &paths, root_dir, false, true);
         if (r < 0)
diff -urN systemd-216/src/shared/label.c systemd-217/src/shared/label.c
--- systemd-216/src/shared/label.c	2014-11-03 09:35:31.270210197 -0800
+++ systemd-217/src/shared/label.c	2014-10-23 12:36:56.911756034 -0700
@@ -19,576 +19,60 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <errno.h>
-#include <unistd.h>
-#include <malloc.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/xattr.h>
-#ifdef HAVE_SELINUX
-#include <selinux/selinux.h>
-#include <selinux/label.h>
-#include <selinux/context.h>
-#endif
-
 #include "label.h"
-#include "strv.h"
 #include "util.h"
-#include "path-util.h"
-#include "selinux-util.h"
-#include "smack-util.h"
-
-#ifdef HAVE_SELINUX
-DEFINE_TRIVIAL_CLEANUP_FUNC(security_context_t, freecon);
-DEFINE_TRIVIAL_CLEANUP_FUNC(context_t, context_free);
-
-#define _cleanup_security_context_free_ _cleanup_(freeconp)
-#define _cleanup_context_free_ _cleanup_(context_freep)
-
-static struct selabel_handle *label_hnd = NULL;
-#endif
-
-static int smack_relabel_in_dev(const char *path) {
-        int r = 0;
-
-#ifdef HAVE_SMACK
-        struct stat sb;
-        const char *label;
-
-        /*
-         * Path must be in /dev and must exist
-         */
-        if (!path_startswith(path, "/dev"))
-                return 0;
-
-        r = lstat(path, &sb);
-        if (r < 0)
-                return -errno;
-
-        /*
-         * Label directories and character devices "*".
-         * Label symlinks "_".
-         * Don't change anything else.
-         */
-        if (S_ISDIR(sb.st_mode))
-                label = SMACK_STAR_LABEL;
-        else if (S_ISLNK(sb.st_mode))
-                label = SMACK_FLOOR_LABEL;
-        else if (S_ISCHR(sb.st_mode))
-                label = SMACK_STAR_LABEL;
-        else
-                return 0;
-
-        r = setxattr(path, "security.SMACK64", label, strlen(label), 0);
-        if (r < 0) {
-                log_error("Smack relabeling \"%s\" %m", path);
-                return -errno;
-        }
-#endif
-
-        return r;
-}
-
-int label_init(const char *prefix) {
-        int r = 0;
-
-#ifdef HAVE_SELINUX
-        usec_t before_timestamp, after_timestamp;
-        struct mallinfo before_mallinfo, after_mallinfo;
-
-        if (!use_selinux())
-                return 0;
-
-        if (label_hnd)
-                return 0;
-
-        before_mallinfo = mallinfo();
-        before_timestamp = now(CLOCK_MONOTONIC);
-
-        if (prefix) {
-                struct selinux_opt options[] = {
-                        { .type = SELABEL_OPT_SUBSET, .value = prefix },
-                };
-
-                label_hnd = selabel_open(SELABEL_CTX_FILE, options, ELEMENTSOF(options));
-        } else
-                label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
-
-        if (!label_hnd) {
-                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
-                         "Failed to initialize SELinux context: %m");
-                r = security_getenforce() == 1 ? -errno : 0;
-        } else  {
-                char timespan[FORMAT_TIMESPAN_MAX];
-                int l;
-
-                after_timestamp = now(CLOCK_MONOTONIC);
-                after_mallinfo = mallinfo();
-
-                l = after_mallinfo.uordblks > before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0;
-
-                log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.",
-                          format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0),
-                          (l+1023)/1024);
-        }
-#endif
-
-        return r;
-}
-
-static int label_fix_selinux(const char *path, bool ignore_enoent, bool ignore_erofs) {
-        int r = 0;
-
-#ifdef HAVE_SELINUX
-        struct stat st;
-        security_context_t fcon;
-
-        if (!label_hnd)
-                return 0;
-
-        r = lstat(path, &st);
-        if (r == 0) {
-                r = selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode);
-
-                /* If there's no label to set, then exit without warning */
-                if (r < 0 && errno == ENOENT)
-                        return 0;
-
-                if (r == 0) {
-                        r = lsetfilecon(path, fcon);
-                        freecon(fcon);
-
-                        /* If the FS doesn't support labels, then exit without warning */
-                        if (r < 0 && errno == ENOTSUP)
-                                return 0;
-                }
-        }
-
-        if (r < 0) {
-                /* Ignore ENOENT in some cases */
-                if (ignore_enoent && errno == ENOENT)
-                        return 0;
-
-                if (ignore_erofs && errno == EROFS)
-                        return 0;
-
-                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
-                         "Unable to fix label of %s: %m", path);
-                r = security_getenforce() == 1 ? -errno : 0;
-        }
-#endif
-
-        return r;
-}
 
 int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
-        int r = 0;
-
-        if (use_selinux()) {
-                r = label_fix_selinux(path, ignore_enoent, ignore_erofs);
-                if (r < 0)
-                        return r;
-        }
-
-        if (use_smack()) {
-                r = smack_relabel_in_dev(path);
-                if (r < 0)
-                        return r;
-        }
-
-        return r;
-}
-
-void label_finish(void) {
-
-#ifdef HAVE_SELINUX
-        if (!use_selinux())
-                return;
-
-        if (label_hnd)
-                selabel_close(label_hnd);
-#endif
-}
-
-int label_get_create_label_from_exe(const char *exe, char **label) {
-
-        int r = 0;
-
-#ifdef HAVE_SELINUX
-        security_context_t mycon = NULL, fcon = NULL;
-        security_class_t sclass;
-
-        if (!use_selinux()) {
-                *label = NULL;
-                return 0;
-        }
-
-        r = getcon(&mycon);
-        if (r < 0)
-                goto fail;
-
-        r = getfilecon(exe, &fcon);
-        if (r < 0)
-                goto fail;
-
-        sclass = string_to_security_class("process");
-        r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label);
-        if (r == 0)
-                log_debug("SELinux Socket context for %s will be set to %s", exe, *label);
-
-fail:
-        if (r < 0 && security_getenforce() == 1)
-                r = -errno;
-
-        freecon(mycon);
-        freecon(fcon);
-#endif
-
-        return r;
-}
+        int r, q;
 
-int label_get_our_label(char **label) {
-        int r = -EOPNOTSUPP;
+        r = mac_selinux_fix(path, ignore_enoent, ignore_erofs);
+        q = mac_smack_fix(path, ignore_enoent, ignore_erofs);
 
-#ifdef HAVE_SELINUX
-        char *l = NULL;
-
-        r = getcon(&l);
         if (r < 0)
                 return r;
+        if (q < 0)
+                return q;
 
-        *label = l;
-#endif
-
-        return r;
+        return 0;
 }
 
-int label_get_child_mls_label(int socket_fd, const char *exe, char **label) {
-        int r = -EOPNOTSUPP;
-
-#ifdef HAVE_SELINUX
-
-        _cleanup_security_context_free_ security_context_t mycon = NULL, peercon = NULL, fcon = NULL, ret = NULL;
-        _cleanup_context_free_ context_t pcon = NULL, bcon = NULL;
-        security_class_t sclass;
-
-        const char *range = NULL;
-
-        assert(socket_fd >= 0);
-        assert(exe);
-        assert(label);
-
-        r = getcon(&mycon);
-        if (r < 0) {
-                r = -EINVAL;
-                goto out;
-        }
-
-        r = getpeercon(socket_fd, &peercon);
-        if (r < 0) {
-                r = -EINVAL;
-                goto out;
-        }
-
-        r = getexeccon(&fcon);
-        if (r < 0) {
-                r = -EINVAL;
-                goto out;
-        }
-
-        if (!fcon) {
-                /* If there is no context set for next exec let's use context
-                   of target executable */
-                r = getfilecon(exe, &fcon);
-                if (r < 0) {
-                        r = -errno;
-                        goto out;
-                }
-        }
-
-        bcon = context_new(mycon);
-        if (!bcon) {
-                r = -ENOMEM;
-                goto out;
-        }
-
-        pcon = context_new(peercon);
-        if (!pcon) {
-                r = -ENOMEM;
-                goto out;
-        }
-
-        range = context_range_get(pcon);
-        if (!range) {
-                r = -errno;
-                goto out;
-        }
-
-        r = context_range_set(bcon, range);
-        if (r) {
-                r = -errno;
-                goto out;
-        }
-
-        freecon(mycon);
-        mycon = context_str(bcon);
-        if (!mycon) {
-                r = -errno;
-                goto out;
-        }
-
-        sclass = string_to_security_class("process");
-        r = security_compute_create(mycon, fcon, sclass, &ret);
-        if (r < 0) {
-                r = -EINVAL;
-                goto out;
-        }
+int mkdir_label(const char *path, mode_t mode) {
+        int r;
 
-        *label = ret;
-        r = 0;
+        assert(path);
 
-out:
-        if (r < 0 && security_getenforce() == 1)
+        r = mac_selinux_create_file_prepare(path, S_IFDIR);
+        if (r < 0)
                 return r;
-#endif
-        return r;
-}
-
-int label_context_set(const char *path, mode_t mode) {
-        int r = 0;
-
-#ifdef HAVE_SELINUX
-        security_context_t filecon = NULL;
 
-        if (!use_selinux() || !label_hnd)
-                return 0;
-
-        r = selabel_lookup_raw(label_hnd, &filecon, path, mode);
-        if (r < 0 && errno != ENOENT)
+        if (mkdir(path, mode) < 0)
                 r = -errno;
-        else if (r == 0) {
-                r = setfscreatecon(filecon);
-                if (r < 0) {
-                        log_error("Failed to set SELinux file context on %s: %m", path);
-                        r = -errno;
-                }
-
-                freecon(filecon);
-        }
-
-        if (r < 0 && security_getenforce() == 0)
-                r = 0;
-#endif
-
-        return r;
-}
 
-int label_socket_set(const char *label) {
+        mac_selinux_create_file_clear();
 
-#ifdef HAVE_SELINUX
-        if (!use_selinux())
-                return 0;
-
-        if (setsockcreatecon((security_context_t) label) < 0) {
-                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
-                         "Failed to set SELinux context (%s) on socket: %m", label);
-
-                if (security_getenforce() == 1)
-                        return -errno;
-        }
-#endif
-
-        return 0;
-}
-
-void label_context_clear(void) {
-
-#ifdef HAVE_SELINUX
-        PROTECT_ERRNO;
-
-        if (!use_selinux())
-                return;
-
-        setfscreatecon(NULL);
-#endif
-}
-
-void label_socket_clear(void) {
-
-#ifdef HAVE_SELINUX
-        PROTECT_ERRNO;
-
-        if (!use_selinux())
-                return;
-
-        setsockcreatecon(NULL);
-#endif
-}
-
-void label_free(const char *label) {
-
-#ifdef HAVE_SELINUX
-        if (!use_selinux())
-                return;
-
-        freecon((security_context_t) label);
-#endif
-}
-
-static int label_mkdir_selinux(const char *path, mode_t mode) {
-        int r = 0;
-
-#ifdef HAVE_SELINUX
-        /* Creates a directory and labels it according to the SELinux policy */
-        security_context_t fcon = NULL;
-
-        if (!label_hnd)
-                return 0;
-
-        if (path_is_absolute(path))
-                r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFDIR);
-        else {
-                _cleanup_free_ char *newpath;
-
-                newpath = path_make_absolute_cwd(path);
-                if (!newpath)
-                        return -ENOMEM;
-
-                r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFDIR);
-        }
-
-        if (r == 0)
-                r = setfscreatecon(fcon);
-
-        if (r < 0 && errno != ENOENT) {
-                log_error("Failed to set security context %s for %s: %m", fcon, path);
-
-                if (security_getenforce() == 1) {
-                        r = -errno;
-                        goto finish;
-                }
-        }
-
-        r = mkdir(path, mode);
         if (r < 0)
-                r = -errno;
-
-finish:
-        setfscreatecon(NULL);
-        freecon(fcon);
-#endif
-
-        return r;
-}
-
-int label_mkdir(const char *path, mode_t mode) {
-        int r;
-
-        if (use_selinux()) {
-                r = label_mkdir_selinux(path, mode);
-                if (r < 0)
-                        return r;
-        }
-
-        if (use_smack()) {
-                r = mkdir(path, mode);
-                if (r < 0 && errno != EEXIST)
-                        return -errno;
-
-                r = smack_relabel_in_dev(path);
-                if (r < 0)
-                        return r;
-        }
-
-        r = mkdir(path, mode);
-        if (r < 0 && errno != EEXIST)
-                return -errno;
+                return r;
 
-        return 0;
+        return mac_smack_fix(path, false, false);
 }
 
-int label_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
-
-        /* Binds a socket and label its file system object according to the SELinux policy */
-
-#ifdef HAVE_SELINUX
-        security_context_t fcon = NULL;
-        const struct sockaddr_un *un;
-        char *path;
+int symlink_label(const char *old_path, const char *new_path) {
         int r;
 
-        assert(fd >= 0);
-        assert(addr);
-        assert(addrlen >= sizeof(sa_family_t));
-
-        if (!use_selinux() || !label_hnd)
-                goto skipped;
-
-        /* Filter out non-local sockets */
-        if (addr->sa_family != AF_UNIX)
-                goto skipped;
-
-        /* Filter out anonymous sockets */
-        if (addrlen < sizeof(sa_family_t) + 1)
-                goto skipped;
+        assert(old_path);
+        assert(new_path);
 
-        /* Filter out abstract namespace sockets */
-        un = (const struct sockaddr_un*) addr;
-        if (un->sun_path[0] == 0)
-                goto skipped;
-
-        path = strndupa(un->sun_path, addrlen - offsetof(struct sockaddr_un, sun_path));
-
-        if (path_is_absolute(path))
-                r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK);
-        else {
-                _cleanup_free_ char *newpath;
-
-                newpath = path_make_absolute_cwd(path);
-                if (!newpath)
-                        return -ENOMEM;
-
-                r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFSOCK);
-        }
-
-        if (r == 0)
-                r = setfscreatecon(fcon);
-
-        if (r < 0 && errno != ENOENT) {
-                log_error("Failed to set security context %s for %s: %m", fcon, path);
-
-                if (security_getenforce() == 1) {
-                        r = -errno;
-                        goto finish;
-                }
-        }
-
-        r = bind(fd, addr, addrlen);
+        r = mac_selinux_create_file_prepare(new_path, S_IFLNK);
         if (r < 0)
+                return r;
+
+        if (symlink(old_path, new_path) < 0)
                 r = -errno;
 
-finish:
-        setfscreatecon(NULL);
-        freecon(fcon);
-
-        return r;
-
-skipped:
-#endif
-        return bind(fd, addr, addrlen) < 0 ? -errno : 0;
-}
+        mac_selinux_create_file_clear();
 
-int label_apply(const char *path, const char *label) {
-        int r = 0;
+        if (r < 0)
+                return r;
 
-#ifdef HAVE_SELINUX
-        if (!use_selinux())
-                return 0;
-
-        r = setfilecon(path, (char *)label);
-#endif
-        return r;
+        return mac_smack_fix(new_path, false, false);
 }
diff -urN systemd-216/src/shared/label.h systemd-217/src/shared/label.h
--- systemd-216/src/shared/label.h	2014-11-03 09:35:30.008197473 -0800
+++ systemd-217/src/shared/label.h	2014-10-23 12:36:56.911756034 -0700
@@ -21,34 +21,10 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <sys/types.h>
-#include <stdbool.h>
-#include <sys/socket.h>
-#include <stdio.h>
-
-int label_init(const char *prefix);
-void label_finish(void);
+#include "selinux-util.h"
+#include "smack-util.h"
 
 int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs);
 
-int label_socket_set(const char *label);
-void label_socket_clear(void);
-
-int label_context_set(const char *path, mode_t mode);
-void label_context_clear(void);
-
-void label_free(const char *label);
-
-int label_get_create_label_from_exe(const char *exe, char **label);
-int label_get_our_label(char **label);
-int label_get_child_mls_label(int socket_fd, const char *exec, char **label);
-
-int label_mkdir(const char *path, mode_t mode);
-
-int label_bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
-
-int label_apply(const char *path, const char *label);
-
-int label_write_one_line_file_atomic(const char *fn, const char *line);
-int label_write_env_file(const char *fname, char **l);
-int label_fopen_temporary(const char *path, FILE **_f, char **_temp_path);
+int mkdir_label(const char *path, mode_t mode);
+int symlink_label(const char *old_path, const char *new_path);
diff -urN systemd-216/src/shared/linux/fanotify.h systemd-217/src/shared/linux/fanotify.h
--- systemd-216/src/shared/linux/fanotify.h	2014-02-12 18:42:33.844684916 -0800
+++ systemd-217/src/shared/linux/fanotify.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,98 +0,0 @@
-#ifndef _LINUX_FANOTIFY_H
-#define _LINUX_FANOTIFY_H
-
-#include <linux/types.h>
-
-/* the following events that user-space can register for */
-#define FAN_ACCESS		0x00000001	/* File was accessed */
-#define FAN_MODIFY		0x00000002	/* File was modified */
-#define FAN_CLOSE_WRITE		0x00000008	/* Unwrittable file closed */
-#define FAN_CLOSE_NOWRITE	0x00000010	/* Writtable file closed */
-#define FAN_OPEN		0x00000020	/* File was opened */
-
-#define FAN_EVENT_ON_CHILD	0x08000000	/* interested in child events */
-
-/* FIXME currently Q's have no limit.... */
-#define FAN_Q_OVERFLOW		0x00004000	/* Event queued overflowed */
-
-#define FAN_OPEN_PERM		0x00010000	/* File open in perm check */
-#define FAN_ACCESS_PERM		0x00020000	/* File accessed in perm check */
-
-/* helper events */
-#define FAN_CLOSE		(FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */
-
-/* flags used for fanotify_init() */
-#define FAN_CLOEXEC		0x00000001
-#define FAN_NONBLOCK		0x00000002
-
-#define FAN_ALL_INIT_FLAGS	(FAN_CLOEXEC | FAN_NONBLOCK)
-
-/* flags used for fanotify_modify_mark() */
-#define FAN_MARK_ADD		0x00000001
-#define FAN_MARK_REMOVE		0x00000002
-#define FAN_MARK_DONT_FOLLOW	0x00000004
-#define FAN_MARK_ONLYDIR	0x00000008
-#define FAN_MARK_MOUNT		0x00000010
-#define FAN_MARK_IGNORED_MASK	0x00000020
-#define FAN_MARK_IGNORED_SURV_MODIFY	0x00000040
-#define FAN_MARK_FLUSH		0x00000080
-
-#define FAN_ALL_MARK_FLAGS	(FAN_MARK_ADD |\
-				 FAN_MARK_REMOVE |\
-				 FAN_MARK_DONT_FOLLOW |\
-				 FAN_MARK_ONLYDIR |\
-				 FAN_MARK_MOUNT |\
-				 FAN_MARK_IGNORED_MASK |\
-				 FAN_MARK_IGNORED_SURV_MODIFY)
-
-/*
- * All of the events - we build the list by hand so that we can add flags in
- * the future and not break backward compatibility.  Apps will get only the
- * events that they originally wanted.  Be sure to add new events here!
- */
-#define FAN_ALL_EVENTS (FAN_ACCESS |\
-			FAN_MODIFY |\
-			FAN_CLOSE |\
-			FAN_OPEN)
-
-/*
- * All events which require a permission response from userspace
- */
-#define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM |\
-			     FAN_ACCESS_PERM)
-
-#define FAN_ALL_OUTGOING_EVENTS	(FAN_ALL_EVENTS |\
-				 FAN_ALL_PERM_EVENTS |\
-				 FAN_Q_OVERFLOW)
-
-#define FANOTIFY_METADATA_VERSION	2
-
-struct fanotify_event_metadata {
-	__u32 event_len;
-	__u32 vers;
-	__u64 mask;
-	__s32 fd;
-	__s32 pid;
-} __attribute__ ((packed));
-
-struct fanotify_response {
-	__s32 fd;
-	__u32 response;
-} __attribute__ ((packed));
-
-/* Legit userspace responses to a _PERM event */
-#define FAN_ALLOW	0x01
-#define FAN_DENY	0x02
-
-/* Helper functions to deal with fanotify_event_metadata buffers */
-#define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))
-
-#define FAN_EVENT_NEXT(meta, len) ((len) -= (meta)->event_len, \
-				   (struct fanotify_event_metadata*)(((char *)(meta)) + \
-				   (meta)->event_len))
-
-#define FAN_EVENT_OK(meta, len)	((long)(len) >= (long)FAN_EVENT_METADATA_LEN && \
-				(long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && \
-				(long)(meta)->event_len <= (long)(len))
-
-#endif /* _LINUX_FANOTIFY_H */
diff -urN systemd-216/src/shared/log.h systemd-217/src/shared/log.h
--- systemd-216/src/shared/log.h	2014-08-11 10:49:12.755442366 -0700
+++ systemd-217/src/shared/log.h	2014-10-23 08:06:27.948110163 -0700
@@ -157,6 +157,12 @@
 #define log_warning(...) log_full(LOG_WARNING, __VA_ARGS__)
 #define log_error(...)   log_full(LOG_ERR,     __VA_ARGS__)
 
+#ifdef LOG_TRACE
+#  define log_trace(...) log_debug(__VA_ARGS__)
+#else
+#  define log_trace(...) do {} while(0)
+#endif
+
 #define log_struct(level, ...) log_struct_internal(level, __FILE__, __LINE__, __func__, __VA_ARGS__)
 
 #define log_oom() log_oom_internal(__FILE__, __LINE__, __func__)
diff -urN systemd-216/src/shared/logs-show.c systemd-217/src/shared/logs-show.c
--- systemd-216/src/shared/logs-show.c	2014-11-03 09:35:36.207259978 -0800
+++ systemd-217/src/shared/logs-show.c	2014-10-22 14:22:47.769220675 -0700
@@ -1155,7 +1155,7 @@
         assert(machine);
         assert(boot_id);
 
-        if (!filename_is_safe(machine))
+        if (!machine_name_is_valid(machine))
                 return -EINVAL;
 
         r = container_get_leader(machine, &pid);
diff -urN systemd-216/src/shared/mempool.c systemd-217/src/shared/mempool.c
--- systemd-216/src/shared/mempool.c	1969-12-31 16:00:00.000000000 -0800
+++ systemd-217/src/shared/mempool.c	2014-10-23 10:00:37.306180793 -0700
@@ -0,0 +1,94 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010-2014 Lennart Poettering
+  Copyright 2014 Michal Schmidt
+
+  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 "mempool.h"
+#include "macro.h"
+#include "util.h"
+
+struct pool {
+        struct pool *next;
+        unsigned n_tiles;
+        unsigned n_used;
+};
+
+void* mempool_alloc_tile(struct mempool *mp) {
+        unsigned i;
+
+        /* When a tile is released we add it to the list and simply
+         * place the next pointer at its offset 0. */
+
+        assert(mp->tile_size >= sizeof(void*));
+        assert(mp->at_least > 0);
+
+        if (mp->freelist) {
+                void *r;
+
+                r = mp->freelist;
+                mp->freelist = * (void**) mp->freelist;
+                return r;
+        }
+
+        if (_unlikely_(!mp->first_pool) ||
+            _unlikely_(mp->first_pool->n_used >= mp->first_pool->n_tiles)) {
+                unsigned n;
+                size_t size;
+                struct pool *p;
+
+                n = mp->first_pool ? mp->first_pool->n_tiles : 0;
+                n = MAX(mp->at_least, n * 2);
+                size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*mp->tile_size);
+                n = (size - ALIGN(sizeof(struct pool))) / mp->tile_size;
+
+                p = malloc(size);
+                if (!p)
+                        return NULL;
+
+                p->next = mp->first_pool;
+                p->n_tiles = n;
+                p->n_used = 0;
+
+                mp->first_pool = p;
+        }
+
+        i = mp->first_pool->n_used++;
+
+        return ((uint8_t*) mp->first_pool) + ALIGN(sizeof(struct pool)) + i*mp->tile_size;
+}
+
+void mempool_free_tile(struct mempool *mp, void *p) {
+        * (void**) p = mp->freelist;
+        mp->freelist = p;
+}
+
+#ifdef VALGRIND
+
+void mempool_drop(struct mempool *mp) {
+        struct pool *p = mp->first_pool;
+        while (p) {
+                struct pool *n;
+                n = p->next;
+                free(p);
+                p = n;
+        }
+}
+
+#endif
diff -urN systemd-216/src/shared/mempool.h systemd-217/src/shared/mempool.h
--- systemd-216/src/shared/mempool.h	1969-12-31 16:00:00.000000000 -0800
+++ systemd-217/src/shared/mempool.h	2014-10-23 10:00:37.306180793 -0700
@@ -0,0 +1,48 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2011-2014 Lennart Poettering
+  Copyright 2014 Michal Schmidt
+
+  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 <stddef.h>
+
+struct pool;
+
+struct mempool {
+        struct pool *first_pool;
+        void *freelist;
+        size_t tile_size;
+        unsigned at_least;
+};
+
+void* mempool_alloc_tile(struct mempool *mp);
+void mempool_free_tile(struct mempool *mp, void *p);
+
+#define DEFINE_MEMPOOL(pool_name, tile_type, alloc_at_least) \
+struct mempool pool_name = { \
+        .tile_size = sizeof(tile_type), \
+        .at_least = alloc_at_least, \
+}
+
+
+#ifdef VALGRIND
+void mempool_drop(struct mempool *mp);
+#endif
diff -urN systemd-216/src/shared/missing.h systemd-217/src/shared/missing.h
--- systemd-216/src/shared/missing.h	2014-11-03 09:35:35.451252355 -0800
+++ systemd-217/src/shared/missing.h	2014-10-22 07:43:01.952137100 -0700
@@ -116,12 +116,6 @@
 #endif
 
 #ifdef __x86_64__
-#  ifndef __NR_fanotify_init
-#    define __NR_fanotify_init 300
-#  endif
-#  ifndef __NR_fanotify_mark
-#    define __NR_fanotify_mark 301
-#  endif
 #  ifndef __NR_memfd_create
 #    define __NR_memfd_create 319
 #  endif
@@ -130,69 +124,16 @@
 #    define __NR_memfd_create 385
 #  endif
 #elif defined _MIPS_SIM
-#  if _MIPS_SIM == _MIPS_SIM_ABI32
-#    ifndef __NR_fanotify_init
-#      define __NR_fanotify_init 4336
-#    endif
-#    ifndef __NR_fanotify_mark
-#      define __NR_fanotify_mark 4337
-#    endif
-#  elif _MIPS_SIM == _MIPS_SIM_NABI32
-#    ifndef __NR_fanotify_init
-#      define __NR_fanotify_init 6300
-#    endif
-#    ifndef __NR_fanotify_mark
-#      define __NR_fanotify_mark 6301
-#    endif
-#  elif _MIPS_SIM == _MIPS_SIM_ABI64
-#    ifndef __NR_fanotify_init
-#      define __NR_fanotify_init 5295
-#    endif
-#    ifndef __NR_fanotify_mark
-#      define __NR_fanotify_mark 5296
-#    endif
-#  endif
 #  ifndef __NR_memfd_create
 #    warning "__NR_memfd_create not yet defined for MIPS"
 #    define __NR_memfd_create 0xffffffff
 #  endif
 #else
-#  ifndef __NR_fanotify_init
-#    define __NR_fanotify_init 338
-#  endif
-#  ifndef __NR_fanotify_mark
-#    define __NR_fanotify_mark 339
-#  endif
 #  ifndef __NR_memfd_create
 #    define __NR_memfd_create 356
 #  endif
 #endif
 
-#ifndef HAVE_FANOTIFY_INIT
-static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags) {
-        return syscall(__NR_fanotify_init, flags, event_f_flags);
-}
-#endif
-
-#ifndef HAVE_FANOTIFY_MARK
-static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t mask,
-                                int dfd, const char *pathname) {
-#if defined _MIPS_SIM && _MIPS_SIM == _MIPS_SIM_ABI32 || defined __powerpc__ && !defined __powerpc64__ \
-    || defined __arm__ && !defined __aarch64__
-        union {
-                uint64_t _64;
-                uint32_t _32[2];
-        } _mask;
-        _mask._64 = mask;
-
-        return syscall(__NR_fanotify_mark, fanotify_fd, flags,
-                       _mask._32[0], _mask._32[1], dfd, pathname);
-#else
-        return syscall(__NR_fanotify_mark, fanotify_fd, flags, mask, dfd, pathname);
-#endif
-}
-#endif
-
 #ifndef HAVE_MEMFD_CREATE
 static inline int memfd_create(const char *name, unsigned int flags) {
         return syscall(__NR_memfd_create, name, flags);
@@ -586,3 +527,12 @@
 #ifndef BPF_XOR
 #  define BPF_XOR 0xa0
 #endif
+
+/* Note that LOOPBACK_IFINDEX is currently not exported by the
+ * kernel/glibc, but hardcoded internally by the kernel.  However, as
+ * it is exported to userspace indirectly via rtnetlink and the
+ * ioctls, and made use of widely we define it here too, in a way that
+ * is compatible with the kernel's internal definition. */
+#ifndef LOOPBACK_IFINDEX
+#define LOOPBACK_IFINDEX 1
+#endif
diff -urN systemd-216/src/shared/mkdir.c systemd-217/src/shared/mkdir.c
--- systemd-216/src/shared/mkdir.c	2014-06-10 14:22:00.386637826 -0700
+++ systemd-217/src/shared/mkdir.c	2014-10-23 12:36:56.971755916 -0700
@@ -58,20 +58,6 @@
         return mkdir_safe_internal(path, mode, uid, gid, mkdir);
 }
 
-int is_dir(const char* path, bool follow) {
-        struct stat st;
-
-        if (follow) {
-                if (stat(path, &st) < 0)
-                        return -errno;
-        } else {
-                if (lstat(path, &st) < 0)
-                        return -errno;
-        }
-
-        return S_ISDIR(st.st_mode);
-}
-
 int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir) {
         const char *p, *e;
         int r;
@@ -144,7 +130,3 @@
 int mkdir_p(const char *path, mode_t mode) {
         return mkdir_p_internal(NULL, path, mode, mkdir);
 }
-
-int mkdir_p_prefix(const char *prefix, const char *path, mode_t mode) {
-        return mkdir_p_internal(prefix, path, mode, mkdir);
-}
diff -urN systemd-216/src/shared/mkdir.h systemd-217/src/shared/mkdir.h
--- systemd-216/src/shared/mkdir.h	2014-07-16 08:24:51.770055760 -0700
+++ systemd-217/src/shared/mkdir.h	2014-10-23 12:36:56.971755916 -0700
@@ -28,18 +28,14 @@
 int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid);
 int mkdir_parents(const char *path, mode_t mode);
 int mkdir_p(const char *path, mode_t mode);
-int mkdir_p_prefix(const char *prefix, const char *path, mode_t mode);
 
-/* selinux versions */
-int mkdir_label(const char *path, mode_t mode);
+/* mandatory access control(MAC) versions */
 int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid);
 int mkdir_parents_label(const char *path, mode_t mode);
 int mkdir_p_label(const char *path, mode_t mode);
-int mkdir_parents_prefix_label(const char *prefix, const char *path, mode_t mode);
 
 /* internally used */
 typedef int (*mkdir_func_t)(const char *pathname, mode_t mode);
 int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir);
 int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir);
 int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, mkdir_func_t _mkdir);
-int is_dir(const char *path, bool is_dir);
diff -urN systemd-216/src/shared/mkdir-label.c systemd-217/src/shared/mkdir-label.c
--- systemd-216/src/shared/mkdir-label.c	2014-03-18 10:05:50.199378175 -0700
+++ systemd-217/src/shared/mkdir-label.c	2014-10-23 12:36:56.911756034 -0700
@@ -32,22 +32,14 @@
 #include "path-util.h"
 #include "mkdir.h"
 
-int mkdir_label(const char *path, mode_t mode) {
-        return label_mkdir(path, mode);
-}
-
 int mkdir_safe_label(const char *path, mode_t mode, uid_t uid, gid_t gid) {
-        return mkdir_safe_internal(path, mode, uid, gid, label_mkdir);
+        return mkdir_safe_internal(path, mode, uid, gid, mkdir_label);
 }
 
 int mkdir_parents_label(const char *path, mode_t mode) {
-        return mkdir_parents_internal(NULL, path, mode, label_mkdir);
-}
-
-int mkdir_parents_prefix_label(const char *prefix, const char *path, mode_t mode) {
-        return mkdir_parents_internal(prefix, path, mode, label_mkdir);
+        return mkdir_parents_internal(NULL, path, mode, mkdir_label);
 }
 
 int mkdir_p_label(const char *path, mode_t mode) {
-        return mkdir_p_internal(NULL, path, mode, label_mkdir);
+        return mkdir_p_internal(NULL, path, mode, mkdir_label);
 }
diff -urN systemd-216/src/shared/selinux-util.c systemd-217/src/shared/selinux-util.c
--- systemd-216/src/shared/selinux-util.c	2014-03-18 10:05:50.206378173 -0700
+++ systemd-217/src/shared/selinux-util.c	2014-10-23 16:12:41.647739370 -0700
@@ -19,33 +19,444 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <errno.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <sys/un.h>
+
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+#include <selinux/context.h>
+#endif
+
+#include "strv.h"
+#include "path-util.h"
 #include "selinux-util.h"
 
 #ifdef HAVE_SELINUX
+DEFINE_TRIVIAL_CLEANUP_FUNC(security_context_t, freecon);
+DEFINE_TRIVIAL_CLEANUP_FUNC(context_t, context_free);
 
-#include <selinux/selinux.h>
+#define _cleanup_security_context_free_ _cleanup_(freeconp)
+#define _cleanup_context_free_ _cleanup_(context_freep)
 
-static int use_selinux_cached = -1;
+static int cached_use = -1;
+static struct selabel_handle *label_hnd = NULL;
 
-bool use_selinux(void) {
+#define log_enforcing(...) log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, __VA_ARGS__)
+#endif
 
-        if (use_selinux_cached < 0)
-                use_selinux_cached = is_selinux_enabled() > 0;
+bool mac_selinux_use(void) {
+#ifdef HAVE_SELINUX
+        if (cached_use < 0)
+                cached_use = is_selinux_enabled() > 0;
 
-        return use_selinux_cached;
+        return cached_use;
+#else
+        return false;
+#endif
 }
 
-void retest_selinux(void) {
-        use_selinux_cached = -1;
+void mac_selinux_retest(void) {
+#ifdef HAVE_SELINUX
+        cached_use = -1;
+#endif
 }
 
-#else
+int mac_selinux_init(const char *prefix) {
+        int r = 0;
 
-bool use_selinux(void) {
-        return false;
+#ifdef HAVE_SELINUX
+        usec_t before_timestamp, after_timestamp;
+        struct mallinfo before_mallinfo, after_mallinfo;
+
+        if (!mac_selinux_use())
+                return 0;
+
+        if (label_hnd)
+                return 0;
+
+        before_mallinfo = mallinfo();
+        before_timestamp = now(CLOCK_MONOTONIC);
+
+        if (prefix) {
+                struct selinux_opt options[] = {
+                        { .type = SELABEL_OPT_SUBSET, .value = prefix },
+                };
+
+                label_hnd = selabel_open(SELABEL_CTX_FILE, options, ELEMENTSOF(options));
+        } else
+                label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
+
+        if (!label_hnd) {
+                log_enforcing("Failed to initialize SELinux context: %m");
+                r = security_getenforce() == 1 ? -errno : 0;
+        } else  {
+                char timespan[FORMAT_TIMESPAN_MAX];
+                int l;
+
+                after_timestamp = now(CLOCK_MONOTONIC);
+                after_mallinfo = mallinfo();
+
+                l = after_mallinfo.uordblks > before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0;
+
+                log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.",
+                          format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0),
+                          (l+1023)/1024);
+        }
+#endif
+
+        return r;
+}
+
+void mac_selinux_finish(void) {
+
+#ifdef HAVE_SELINUX
+        if (!label_hnd)
+                return;
+
+        selabel_close(label_hnd);
+#endif
 }
 
-void retest_selinux(void) {
+int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
+
+#ifdef HAVE_SELINUX
+        struct stat st;
+        int r;
+
+        assert(path);
+
+        /* if mac_selinux_init() wasn't called before we are a NOOP */
+        if (!label_hnd)
+                return 0;
+
+        r = lstat(path, &st);
+        if (r >= 0) {
+                _cleanup_security_context_free_ security_context_t fcon = NULL;
+
+                r = selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode);
+
+                /* If there's no label to set, then exit without warning */
+                if (r < 0 && errno == ENOENT)
+                        return 0;
+
+                if (r >= 0) {
+                        r = lsetfilecon(path, fcon);
+
+                        /* If the FS doesn't support labels, then exit without warning */
+                        if (r < 0 && errno == ENOTSUP)
+                                return 0;
+                }
+        }
+
+        if (r < 0) {
+                /* Ignore ENOENT in some cases */
+                if (ignore_enoent && errno == ENOENT)
+                        return 0;
+
+                if (ignore_erofs && errno == EROFS)
+                        return 0;
+
+                log_enforcing("Unable to fix SELinux security context of %s: %m", path);
+                if (security_getenforce() == 1)
+                        return -errno;
+        }
+#endif
+
+        return 0;
 }
 
+int mac_selinux_apply(const char *path, const char *label) {
+
+#ifdef HAVE_SELINUX
+        assert(path);
+        assert(label);
+
+        if (!mac_selinux_use())
+                return 0;
+
+        if (setfilecon(path, (security_context_t) label) < 0) {
+                log_enforcing("Failed to set SELinux security context %s on path %s: %m", label, path);
+                if (security_getenforce() == 1)
+                        return -errno;
+        }
 #endif
+        return 0;
+}
+
+int mac_selinux_get_create_label_from_exe(const char *exe, char **label) {
+        int r = -EOPNOTSUPP;
+
+#ifdef HAVE_SELINUX
+        _cleanup_security_context_free_ security_context_t mycon = NULL, fcon = NULL;
+        security_class_t sclass;
+
+        assert(exe);
+        assert(label);
+
+        if (!mac_selinux_use())
+                return -EOPNOTSUPP;
+
+        r = getcon(&mycon);
+        if (r < 0)
+                return -errno;
+
+        r = getfilecon(exe, &fcon);
+        if (r < 0)
+                return -errno;
+
+        sclass = string_to_security_class("process");
+        r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label);
+        if (r < 0)
+                return -errno;
+#endif
+
+        return r;
+}
+
+int mac_selinux_get_our_label(char **label) {
+        int r = -EOPNOTSUPP;
+
+        assert(label);
+
+#ifdef HAVE_SELINUX
+        if (!mac_selinux_use())
+                return -EOPNOTSUPP;
+
+        r = getcon(label);
+        if (r < 0)
+                return -errno;
+#endif
+
+        return r;
+}
+
+int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, char **label) {
+        int r = -EOPNOTSUPP;
+
+#ifdef HAVE_SELINUX
+        _cleanup_security_context_free_ security_context_t mycon = NULL, peercon = NULL, fcon = NULL;
+        _cleanup_context_free_ context_t pcon = NULL, bcon = NULL;
+        security_class_t sclass;
+        const char *range = NULL;
+
+        assert(socket_fd >= 0);
+        assert(exe);
+        assert(label);
+
+        if (!mac_selinux_use())
+                return -EOPNOTSUPP;
+
+        r = getcon(&mycon);
+        if (r < 0)
+                return -errno;
+
+        r = getpeercon(socket_fd, &peercon);
+        if (r < 0)
+                return -errno;
+
+        r = getexeccon(&fcon);
+        if (r < 0)
+                return -errno;
+
+        if (!fcon) {
+                /* If there is no context set for next exec let's use context
+                   of target executable */
+                r = getfilecon(exe, &fcon);
+                if (r < 0)
+                        return -errno;
+        }
+
+        bcon = context_new(mycon);
+        if (!bcon)
+                return -ENOMEM;
+
+        pcon = context_new(peercon);
+        if (!pcon)
+                return -ENOMEM;
+
+        range = context_range_get(pcon);
+        if (!range)
+                return -errno;
+
+        r = context_range_set(bcon, range);
+        if (r)
+                return -errno;
+
+        freecon(mycon);
+        mycon = strdup(context_str(bcon));
+        if (!mycon)
+                return -ENOMEM;
+
+        sclass = string_to_security_class("process");
+        r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label);
+        if (r < 0)
+                return -errno;
+#endif
+
+        return r;
+}
+
+void mac_selinux_free(char *label) {
+
+#ifdef HAVE_SELINUX
+        if (!mac_selinux_use())
+                return;
+
+        freecon((security_context_t) label);
+#endif
+}
+
+int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
+        int r = 0;
+
+#ifdef HAVE_SELINUX
+        _cleanup_security_context_free_ security_context_t filecon = NULL;
+
+        assert(path);
+
+        if (!label_hnd)
+                return 0;
+
+        if (path_is_absolute(path))
+                r = selabel_lookup_raw(label_hnd, &filecon, path, mode);
+        else {
+                _cleanup_free_ char *newpath;
+
+                newpath = path_make_absolute_cwd(path);
+                if (!newpath)
+                        return -ENOMEM;
+
+                r = selabel_lookup_raw(label_hnd, &filecon, newpath, mode);
+        }
+
+        if (r < 0 && errno != ENOENT)
+                r = -errno;
+        else if (r == 0) {
+                r = setfscreatecon(filecon);
+                if (r < 0) {
+                        log_enforcing("Failed to set SELinux security context %s for %s: %m", filecon, path);
+                        r = -errno;
+                }
+        }
+
+        if (r < 0 && security_getenforce() == 0)
+                r = 0;
+#endif
+
+        return r;
+}
+
+void mac_selinux_create_file_clear(void) {
+
+#ifdef HAVE_SELINUX
+        PROTECT_ERRNO;
+
+        if (!mac_selinux_use())
+                return;
+
+        setfscreatecon(NULL);
+#endif
+}
+
+int mac_selinux_create_socket_prepare(const char *label) {
+
+#ifdef HAVE_SELINUX
+        if (!mac_selinux_use())
+                return 0;
+
+        assert(label);
+
+        if (setsockcreatecon((security_context_t) label) < 0) {
+                log_enforcing("Failed to set SELinux security context %s for sockets: %m", label);
+
+                if (security_getenforce() == 1)
+                        return -errno;
+        }
+#endif
+
+        return 0;
+}
+
+void mac_selinux_create_socket_clear(void) {
+
+#ifdef HAVE_SELINUX
+        PROTECT_ERRNO;
+
+        if (!mac_selinux_use())
+                return;
+
+        setsockcreatecon(NULL);
+#endif
+}
+
+int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
+
+        /* Binds a socket and label its file system object according to the SELinux policy */
+
+#ifdef HAVE_SELINUX
+        _cleanup_security_context_free_ security_context_t fcon = NULL;
+        const struct sockaddr_un *un;
+        char *path;
+        int r;
+
+        assert(fd >= 0);
+        assert(addr);
+        assert(addrlen >= sizeof(sa_family_t));
+
+        if (!label_hnd)
+                goto skipped;
+
+        /* Filter out non-local sockets */
+        if (addr->sa_family != AF_UNIX)
+                goto skipped;
+
+        /* Filter out anonymous sockets */
+        if (addrlen < sizeof(sa_family_t) + 1)
+                goto skipped;
+
+        /* Filter out abstract namespace sockets */
+        un = (const struct sockaddr_un*) addr;
+        if (un->sun_path[0] == 0)
+                goto skipped;
+
+        path = strndupa(un->sun_path, addrlen - offsetof(struct sockaddr_un, sun_path));
+
+        if (path_is_absolute(path))
+                r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK);
+        else {
+                _cleanup_free_ char *newpath;
+
+                newpath = path_make_absolute_cwd(path);
+                if (!newpath)
+                        return -ENOMEM;
+
+                r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFSOCK);
+        }
+
+        if (r == 0)
+                r = setfscreatecon(fcon);
+
+        if (r < 0 && errno != ENOENT) {
+                log_enforcing("Failed to set SELinux security context %s for %s: %m", fcon, path);
+
+                if (security_getenforce() == 1) {
+                        r = -errno;
+                        goto finish;
+                }
+        }
+
+        r = bind(fd, addr, addrlen);
+        if (r < 0)
+                r = -errno;
+
+finish:
+        setfscreatecon(NULL);
+        return r;
+
+skipped:
+#endif
+        return bind(fd, addr, addrlen) < 0 ? -errno : 0;
+}
diff -urN systemd-216/src/shared/selinux-util.h systemd-217/src/shared/selinux-util.h
--- systemd-216/src/shared/selinux-util.h	2014-02-12 18:42:33.907684661 -0800
+++ systemd-217/src/shared/selinux-util.h	2014-10-23 12:36:56.911756034 -0700
@@ -21,7 +21,28 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <sys/socket.h>
+#include <stdio.h>
 #include <stdbool.h>
 
-bool use_selinux(void);
-void retest_selinux(void);
+bool mac_selinux_use(void);
+void mac_selinux_retest(void);
+
+int mac_selinux_init(const char *prefix);
+void mac_selinux_finish(void);
+
+int mac_selinux_fix(const char *path, bool ignore_enoent, bool ignore_erofs);
+int mac_selinux_apply(const char *path, const char *label);
+
+int mac_selinux_get_create_label_from_exe(const char *exe, char **label);
+int mac_selinux_get_our_label(char **label);
+int mac_selinux_get_child_mls_label(int socket_fd, const char *exec, char **label);
+void mac_selinux_free(char *label);
+
+int mac_selinux_create_file_prepare(const char *path, mode_t mode);
+void mac_selinux_create_file_clear(void);
+
+int mac_selinux_create_socket_prepare(const char *label);
+void mac_selinux_create_socket_clear(void);
+
+int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
diff -urN systemd-216/src/shared/set.c systemd-217/src/shared/set.c
--- systemd-216/src/shared/set.c	2014-11-03 09:35:27.951176732 -0800
+++ systemd-217/src/shared/set.c	2014-10-23 10:00:37.307180853 -0700
@@ -137,7 +137,11 @@
         return hashmap_merge(MAKE_HASHMAP(s), MAKE_HASHMAP(other));
 }
 
-void set_move(Set *s, Set *other) {
+int set_reserve(Set *s, unsigned entries_add) {
+        return hashmap_reserve(MAKE_HASHMAP(s), entries_add);
+}
+
+int set_move(Set *s, Set *other) {
         return hashmap_move(MAKE_HASHMAP(s), MAKE_HASHMAP(other));
 }
 
diff -urN systemd-216/src/shared/set.h systemd-217/src/shared/set.h
--- systemd-216/src/shared/set.h	2014-11-03 09:35:27.952176742 -0800
+++ systemd-217/src/shared/set.h	2014-10-23 10:00:37.307180853 -0700
@@ -50,7 +50,8 @@
 int set_remove_and_put(Set *s, void *old_value, void *new_value);
 
 int set_merge(Set *s, Set *other);
-void set_move(Set *s, Set *other);
+int set_reserve(Set *s, unsigned entries_add);
+int set_move(Set *s, Set *other);
 int set_move_one(Set *s, Set *other, void *value);
 
 unsigned set_size(Set *s);
diff -urN systemd-216/src/shared/smack-util.c systemd-217/src/shared/smack-util.c
--- systemd-216/src/shared/smack-util.c	2014-05-28 03:53:43.921243412 -0700
+++ systemd-217/src/shared/smack-util.c	2014-10-23 12:36:56.667756513 -0700
@@ -21,69 +21,163 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <unistd.h>
-#include <string.h>
 #include <sys/xattr.h>
 
+#include "util.h"
+#include "path-util.h"
 #include "smack-util.h"
 
-bool use_smack(void) {
+#define SMACK_FLOOR_LABEL "_"
+#define SMACK_STAR_LABEL  "*"
+
+bool mac_smack_use(void) {
 #ifdef HAVE_SMACK
-        static int use_smack_cached = -1;
+        static int cached_use = -1;
 
-        if (use_smack_cached < 0)
-                use_smack_cached = access("/sys/fs/smackfs/", F_OK) >= 0;
+        if (cached_use < 0)
+                cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
 
-        return use_smack_cached;
+        return cached_use;
 #else
         return false;
 #endif
+}
+
+int mac_smack_apply(const char *path, const char *label) {
+        int r = 0;
 
+        assert(path);
+
+#ifdef HAVE_SMACK
+        if (!mac_smack_use())
+                return 0;
+
+        if (label)
+                r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
+        else
+                r = lremovexattr(path, "security.SMACK64");
+        if (r < 0)
+                return -errno;
+#endif
+
+        return r;
 }
 
-int smack_label_path(const char *path, const char *label) {
+int mac_smack_apply_fd(int fd, const char *label) {
+        int r = 0;
+
+        assert(fd >= 0);
+
 #ifdef HAVE_SMACK
-        if (!use_smack())
+        if (!mac_smack_use())
                 return 0;
 
         if (label)
-                return setxattr(path, "security.SMACK64", label, strlen(label), 0);
+                r = fsetxattr(fd, "security.SMACK64", label, strlen(label), 0);
         else
-                return lremovexattr(path, "security.SMACK64");
-#else
-        return 0;
+                r = fremovexattr(fd, "security.SMACK64");
+        if (r < 0)
+                return -errno;
 #endif
+
+        return r;
 }
 
-int smack_label_fd(int fd, const char *label) {
+int mac_smack_apply_ip_out_fd(int fd, const char *label) {
+        int r = 0;
+
+        assert(fd >= 0);
+
 #ifdef HAVE_SMACK
-        if (!use_smack())
+        if (!mac_smack_use())
                 return 0;
 
-        return fsetxattr(fd, "security.SMACK64", label, strlen(label), 0);
-#else
-        return 0;
+        if (label)
+                r = fsetxattr(fd, "security.SMACK64IPOUT", label, strlen(label), 0);
+        else
+                r = fremovexattr(fd, "security.SMACK64IPOUT");
+        if (r < 0)
+                return -errno;
 #endif
+
+        return r;
 }
 
-int smack_label_ip_out_fd(int fd, const char *label) {
+int mac_smack_apply_ip_in_fd(int fd, const char *label) {
+        int r = 0;
+
+        assert(fd >= 0);
+
 #ifdef HAVE_SMACK
-        if (!use_smack())
+        if (!mac_smack_use())
                 return 0;
 
-        return fsetxattr(fd, "security.SMACK64IPOUT", label, strlen(label), 0);
-#else
-        return 0;
+        if (label)
+                r = fsetxattr(fd, "security.SMACK64IPIN", label, strlen(label), 0);
+        else
+                r = fremovexattr(fd, "security.SMACK64IPIN");
+        if (r < 0)
+                return -errno;
 #endif
+
+        return r;
 }
 
-int smack_label_ip_in_fd(int fd, const char *label) {
+int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs) {
+        int r = 0;
+
 #ifdef HAVE_SMACK
-        if (!use_smack())
+        struct stat st;
+
+        assert(path);
+
+        if (!mac_smack_use())
                 return 0;
 
-        return fsetxattr(fd, "security.SMACK64IPIN", label, strlen(label), 0);
-#else
-        return 0;
+        /*
+         * Path must be in /dev and must exist
+         */
+        if (!path_startswith(path, "/dev"))
+                return 0;
+
+        r = lstat(path, &st);
+        if (r >= 0) {
+                const char *label;
+
+                /*
+                 * Label directories and character devices "*".
+                 * Label symlinks "_".
+                 * Don't change anything else.
+                 */
+
+                if (S_ISDIR(st.st_mode))
+                        label = SMACK_STAR_LABEL;
+                else if (S_ISLNK(st.st_mode))
+                        label = SMACK_FLOOR_LABEL;
+                else if (S_ISCHR(st.st_mode))
+                        label = SMACK_STAR_LABEL;
+                else
+                        return 0;
+
+                r = lsetxattr(path, "security.SMACK64", label, strlen(label), 0);
+
+                /* If the FS doesn't support labels, then exit without warning */
+                if (r < 0 && errno == ENOTSUP)
+                        return 0;
+        }
+
+        if (r < 0) {
+                /* Ignore ENOENT in some cases */
+                if (ignore_enoent && errno == ENOENT)
+                        return 0;
+
+                if (ignore_erofs && errno == EROFS)
+                        return 0;
+
+                log_debug("Unable to fix SMACK label of %s: %m", path);
+                r = -errno;
+        }
 #endif
+
+        return r;
 }
diff -urN systemd-216/src/shared/smack-util.h systemd-217/src/shared/smack-util.h
--- systemd-216/src/shared/smack-util.h	2014-02-24 08:36:17.816544500 -0800
+++ systemd-217/src/shared/smack-util.h	2014-10-23 12:36:56.668756511 -0700
@@ -25,12 +25,11 @@
 
 #include <stdbool.h>
 
-#define SMACK_FLOOR_LABEL "_"
-#define SMACK_STAR_LABEL  "*"
+bool mac_smack_use(void);
 
-bool use_smack(void);
+int mac_smack_fix(const char *path, bool ignore_enoent, bool ignore_erofs);
 
-int smack_label_path(const char *path, const char *label);
-int smack_label_fd(int fd, const char *label);
-int smack_label_ip_in_fd(int fd, const char *label);
-int smack_label_ip_out_fd(int fd, const char *label);
+int mac_smack_apply(const char *path, const char *label);
+int mac_smack_apply_fd(int fd, const char *label);
+int mac_smack_apply_ip_in_fd(int fd, const char *label);
+int mac_smack_apply_ip_out_fd(int fd, const char *label);
diff -urN systemd-216/src/shared/socket-label.c systemd-217/src/shared/socket-label.c
--- systemd-216/src/shared/socket-label.c	2014-07-16 08:24:51.770055760 -0700
+++ systemd-217/src/shared/socket-label.c	2014-10-23 12:36:56.810756232 -0700
@@ -64,7 +64,7 @@
                 return -EAFNOSUPPORT;
 
         if (label) {
-                r = label_socket_set(label);
+                r = mac_selinux_create_socket_prepare(label);
                 if (r < 0)
                         return r;
         }
@@ -73,7 +73,7 @@
         r = fd < 0 ? -errno : 0;
 
         if (label)
-                label_socket_clear();
+                mac_selinux_create_socket_clear();
 
         if (r < 0)
                 return r;
@@ -119,7 +119,7 @@
                 /* Include the original umask in our mask */
                 umask(~socket_mode | old_mask);
 
-                r = label_bind(fd, &a->sockaddr.sa, a->size);
+                r = mac_selinux_bind(fd, &a->sockaddr.sa, a->size);
 
                 if (r < 0 && errno == EADDRINUSE) {
                         /* Unlink and try again */
@@ -150,7 +150,8 @@
 
         r = socket_address_parse(&a, address);
         if (r < 0) {
-                log_error("Failed to parse socket: %s", strerror(-r));
+                log_error("Failed to parse socket address \"%s\": %s",
+                          address, strerror(-r));
                 return r;
         }
 
diff -urN systemd-216/src/shared/socket-util.c systemd-217/src/shared/socket-util.c
--- systemd-216/src/shared/socket-util.c	2014-08-15 04:19:03.716787816 -0700
+++ systemd-217/src/shared/socket-util.c	2014-10-23 08:06:27.948110163 -0700
@@ -633,20 +633,20 @@
         r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
                         NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
         if (r != 0) {
-                _cleanup_free_ char *sockname = NULL;
                 int saved_errno = errno;
 
-                r = sockaddr_pretty(&sa->sa, salen, true, &sockname);
-                if (r < 0)
+                r = sockaddr_pretty(&sa->sa, salen, true, &ret);
+                if (r < 0) {
                         log_error("sockadd_pretty() failed: %s", strerror(-r));
-                else
-                        log_error("getnameinfo(%s) failed: %s", sockname, strerror(-r));
-                return -saved_errno;
-        }
+                        return r;
+                }
 
-        ret = strdup(host);
-        if (!ret)
-                return log_oom();
+                log_debug("getnameinfo(%s) failed: %s", ret, strerror(saved_errno));
+        } else {
+                ret = strdup(host);
+                if (!ret)
+                        return log_oom();
+        }
 
         *_ret = ret;
         return 0;
diff -urN systemd-216/src/shared/strv.c systemd-217/src/shared/strv.c
--- systemd-216/src/shared/strv.c	2014-11-03 09:35:21.370110375 -0800
+++ systemd-217/src/shared/strv.c	2014-10-22 02:45:12.074731037 -0700
@@ -380,13 +380,19 @@
 
 int strv_push(char ***l, char *value) {
         char **c;
-        unsigned n;
+        unsigned n, m;
 
         if (!value)
                 return 0;
 
         n = strv_length(*l);
-        c = realloc(*l, sizeof(char*) * (n + 2));
+
+        /* increase and check for overflow */
+        m = n + 2;
+        if (m < n)
+                return -ENOMEM;
+
+        c = realloc_multiply(*l, sizeof(char*), m);
         if (!c)
                 return -ENOMEM;
 
@@ -399,13 +405,19 @@
 
 int strv_push_prepend(char ***l, char *value) {
         char **c;
-        unsigned n, i;
+        unsigned n, m, i;
 
         if (!value)
                 return 0;
 
         n = strv_length(*l);
-        c = new(char*, n + 2);
+
+        /* increase and check for overflow */
+        m = n + 2;
+        if (m < n)
+                return -ENOMEM;
+
+        c = new(char*, m);
         if (!c)
                 return -ENOMEM;
 
diff -urN systemd-216/src/shared/test-tables.h systemd-217/src/shared/test-tables.h
--- systemd-216/src/shared/test-tables.h	2014-07-16 16:41:52.142037134 -0700
+++ systemd-217/src/shared/test-tables.h	2014-10-28 10:05:59.686755486 -0700
@@ -40,10 +40,9 @@
                         rev = reverse("--no-such--value----");
 
                 printf("%s: %d → %s → %d\n", name, i, val, rev);
-                if (i >= 0 && i < size ?
-                    sparse ? rev != i && rev != -1 : val == NULL || rev != i :
-                    val != NULL || rev != -1)
-                        exit(EXIT_FAILURE);
+                assert_se(!(i >= 0 && i < size ?
+                            sparse ? rev != i && rev != -1 : val == NULL || rev != i :
+                            val != NULL || rev != -1));
         }
 }
 
diff -urN systemd-216/src/shared/time-util.c systemd-217/src/shared/time-util.c
--- systemd-216/src/shared/time-util.c	2014-11-03 09:35:36.208259988 -0800
+++ systemd-217/src/shared/time-util.c	2014-10-24 10:09:14.762923034 -0700
@@ -49,25 +49,20 @@
         int64_t delta;
         assert(ts);
 
-        if (u == USEC_INFINITY) {
-                ts->realtime = ts->monotonic = USEC_INFINITY;
+        if (u == USEC_INFINITY || u <= 0) {
+                ts->realtime = ts->monotonic = u;
                 return ts;
         }
 
         ts->realtime = u;
 
-        if (u == 0)
-                ts->monotonic = 0;
-        else {
-                delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
+        delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
+        ts->monotonic = now(CLOCK_MONOTONIC);
 
-                ts->monotonic = now(CLOCK_MONOTONIC);
-
-                if ((int64_t) ts->monotonic > delta)
-                        ts->monotonic -= delta;
-                else
-                        ts->monotonic = 0;
-        }
+        if ((int64_t) ts->monotonic > delta)
+                ts->monotonic -= delta;
+        else
+                ts->monotonic = 0;
 
         return ts;
 }
@@ -219,11 +214,10 @@
         const char *s;
         usec_t n, d;
 
-        n = now(CLOCK_REALTIME);
-
-        if (t <= 0 || (t == USEC_INFINITY))
+        if (t <= 0 || t == USEC_INFINITY)
                 return NULL;
 
+        n = now(CLOCK_REALTIME);
         if (n > t) {
                 d = n - t;
                 s = "ago";
@@ -302,8 +296,14 @@
         assert(buf);
         assert(l > 0);
 
-        if (t == USEC_INFINITY || t <= 0) {
-                strncpy(p, t == USEC_INFINITY ? "infinity" : "0", l);
+        if (t == USEC_INFINITY) {
+                strncpy(p, "infinity", l-1);
+                p[l-1] = 0;
+                return p;
+        }
+
+        if (t <= 0) {
+                strncpy(p, "0", l-1);
                 p[l-1] = 0;
                 return p;
         }
@@ -773,7 +773,7 @@
                 { "", 1ULL }, /* default is nsec */
         };
 
-        const char *p;
+        const char *p, *s;
         nsec_t r = 0;
         bool something = false;
 
@@ -781,6 +781,18 @@
         assert(nsec);
 
         p = t;
+
+        p += strspn(p, WHITESPACE);
+        s = startswith(p, "infinity");
+        if (s) {
+                s += strspn(s, WHITESPACE);
+                if (!*s != 0)
+                        return -EINVAL;
+
+                *nsec = NSEC_INFINITY;
+                return 0;
+        }
+
         for (;;) {
                 long long l, z = 0;
                 char *e;
diff -urN systemd-216/src/shared/time-util.h systemd-217/src/shared/time-util.h
--- systemd-216/src/shared/time-util.h	2014-11-03 09:35:36.208259988 -0800
+++ systemd-217/src/shared/time-util.h	2014-10-20 15:38:24.820469344 -0700
@@ -65,6 +65,8 @@
 #define FORMAT_TIMESTAMP_RELATIVE_MAX 256
 #define FORMAT_TIMESPAN_MAX 64
 
+#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
+
 #define DUAL_TIMESTAMP_NULL ((struct dual_timestamp) { 0, 0 })
 
 usec_t now(clockid_t clock);
diff -urN systemd-216/src/shared/util.c systemd-217/src/shared/util.c
--- systemd-216/src/shared/util.c	2014-11-03 09:35:36.235260260 -0800
+++ systemd-217/src/shared/util.c	2014-10-27 05:05:47.378351406 -0700
@@ -6933,10 +6933,21 @@
         if (lstat(path, &info) < 0)
                 return -errno;
 
-        if (S_ISLNK(info.st_mode))
-                return 1;
+        return !!S_ISLNK(info.st_mode);
+}
 
-        return 0;
+int is_dir(const char* path, bool follow) {
+        struct stat st;
+
+        if (follow) {
+                if (stat(path, &st) < 0)
+                        return -errno;
+        } else {
+                if (lstat(path, &st) < 0)
+                        return -errno;
+        }
+
+        return !!S_ISDIR(st.st_mode);
 }
 
 int unquote_first_word(const char **p, char **ret) {
@@ -7164,3 +7175,23 @@
 
         return 0;
 }
+
+int sethostname_idempotent(const char *s) {
+        int r;
+        char buf[HOST_NAME_MAX + 1] = {};
+
+        assert(s);
+
+        r = gethostname(buf, sizeof(buf));
+        if (r < 0)
+                return -errno;
+
+        if (streq(buf, s))
+                return 0;
+
+        r = sethostname(s, strlen(s));
+        if (r < 0)
+                return -errno;
+
+        return 1;
+}
diff -urN systemd-216/src/shared/util.h systemd-217/src/shared/util.h
--- systemd-216/src/shared/util.h	2014-11-03 09:35:31.168209169 -0800
+++ systemd-217/src/shared/util.h	2014-10-27 04:48:29.297966272 -0700
@@ -991,8 +991,11 @@
 int take_password_lock(const char *root);
 
 int is_symlink(const char *path);
+int is_dir(const char *path, bool follow);
 
 int unquote_first_word(const char **p, char **ret);
 int unquote_many_words(const char **p, ...) _sentinel_;
 
 int free_and_strdup(char **p, const char *s);
+
+int sethostname_idempotent(const char *s);
diff -urN systemd-216/src/systemctl/systemctl.c systemd-217/src/systemctl/systemctl.c
--- systemd-216/src/systemctl/systemctl.c	2014-11-03 09:35:36.873266693 -0800
+++ systemd-217/src/systemctl/systemctl.c	2014-11-03 09:33:48.707176055 -0800
@@ -137,23 +137,6 @@
 static OutputMode arg_output = OUTPUT_SHORT;
 static bool arg_plain = false;
 
-static const struct {
-        const char *verb;
-        const char *method;
-} unit_actions[] = {
-        { "start",                 "StartUnit" },
-        { "stop",                  "StopUnit" },
-        { "condstop",              "StopUnit" },
-        { "reload",                "ReloadUnit" },
-        { "restart",               "RestartUnit" },
-        { "try-restart",           "TryRestartUnit" },
-        { "condrestart",           "TryRestartUnit" },
-        { "reload-or-restart",     "ReloadOrRestartUnit" },
-        { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
-        { "condreload",            "ReloadOrTryRestartUnit" },
-        { "force-reload",          "ReloadOrTryRestartUnit" }
-};
-
 static bool original_stdout_is_tty;
 
 static int daemon_reload(sd_bus *bus, char **args);
@@ -318,21 +301,37 @@
 }
 
 static bool output_show_unit(const UnitInfo *u, char **patterns) {
-        const char *dot;
-
         if (!strv_isempty(patterns)) {
                 char **pattern;
 
                 STRV_FOREACH(pattern, patterns)
                         if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
-                                return true;
+                                goto next;
                 return false;
         }
 
-        return (!arg_types || ((dot = strrchr(u->id, '.')) &&
-                               strv_find(arg_types, dot+1))) &&
-                (arg_all || !(streq(u->active_state, "inactive")
-                              || u->following[0]) || u->job_id > 0);
+next:
+        if (arg_types) {
+                const char *dot;
+
+                dot = strrchr(u->id, '.');
+                if (!dot)
+                        return false;
+
+                if (!strv_find(arg_types, dot+1))
+                        return false;
+        }
+
+        if (arg_all)
+                return true;
+
+        if (u->job_id > 0)
+                return true;
+
+        if (streq(u->active_state, "inactive") || u->following[0])
+                return false;
+
+        return true;
 }
 
 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
@@ -1248,18 +1247,33 @@
 }
 
 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
-        const char *dot;
-
         if (!strv_isempty(patterns)) {
                 char **pattern;
 
                 STRV_FOREACH(pattern, patterns)
                         if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
-                                return true;
+                                goto next;
                 return false;
         }
 
-        return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
+next:
+        if (!strv_isempty(arg_types)) {
+                const char *dot;
+
+                dot = strrchr(u->path, '.');
+                if (!dot)
+                        return false;
+
+                if (!strv_find(arg_types, dot+1))
+                        return false;
+        }
+
+        if (!strv_isempty(arg_states)) {
+                if (!strv_find(arg_states, unit_file_state_to_string(u->state)))
+                        return false;
+        }
+
+        return true;
 }
 
 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
@@ -1982,18 +1996,28 @@
 
                 r = 0;
         } else {
-                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
 
-                r = sd_bus_call_method(
+                r = sd_bus_message_new_method_call(
                                 bus,
+                                &m,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "SetDefaultTarget",
-                                &error,
-                                &reply,
-                                "sb", unit, true);
+                                "SetDefaultTarget");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append(m, "sb", unit, 1);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_call(bus, m, 0, &error, &reply);
                 if (r < 0) {
                         log_error("Failed to set default target: %s", bus_error_message(&error, -r));
                         return r;
@@ -2160,6 +2184,7 @@
 static int cancel_job(sd_bus *bus, char **args) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         char **name;
+        int r = 0;
 
         assert(args);
 
@@ -2167,31 +2192,43 @@
                 return daemon_reload(bus, args);
 
         STRV_FOREACH(name, args+1) {
+                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
                 uint32_t id;
-                int r;
+                int q;
 
-                r = safe_atou32(*name, &id);
-                if (r < 0) {
-                        log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
-                        return r;
+                q = safe_atou32(*name, &id);
+                if (q < 0) {
+                        log_error("Failed to parse job id \"%s\": %s", *name, strerror(-q));
+                        return q;
                 }
 
-                r = sd_bus_call_method(
+                q = sd_bus_message_new_method_call(
                                 bus,
+                                &m,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "CancelJob",
-                                &error,
-                                NULL,
-                                "u", id);
-                if (r < 0) {
-                        log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, r));
-                        return r;
+                                "CancelJob");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (q < 0)
+                        return bus_log_create_error(1);
+
+                q = sd_bus_message_append(m, "u", id);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_call(bus, m, 0, &error, NULL);
+                if (q < 0) {
+                        log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
+                        if (r == 0)
+                                r = q;
                 }
         }
 
-        return 0;
+        return r;
 }
 
 static int need_daemon_reload(sd_bus *bus, const char *unit) {
@@ -2539,6 +2576,23 @@
         return 0;
 }
 
+static const struct {
+        const char *verb;
+        const char *method;
+} unit_actions[] = {
+        { "start",                 "StartUnit" },
+        { "stop",                  "StopUnit" },
+        { "condstop",              "StopUnit" },
+        { "reload",                "ReloadUnit" },
+        { "restart",               "RestartUnit" },
+        { "try-restart",           "TryRestartUnit" },
+        { "condrestart",           "TryRestartUnit" },
+        { "reload-or-restart",     "ReloadOrRestartUnit" },
+        { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
+        { "condreload",            "ReloadOrTryRestartUnit" },
+        { "force-reload",          "ReloadOrTryRestartUnit" }
+};
+
 static const char *verb_to_method(const char *verb) {
        uint i;
 
@@ -2567,7 +2621,7 @@
                 sd_bus_error *error,
                 Set *s) {
 
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
         const char *path;
         int r;
 
@@ -2577,15 +2631,26 @@
         assert(error);
 
         log_debug("Calling manager for %s on %s, %s", method, name, mode);
-        r = sd_bus_call_method(
+
+        r = sd_bus_message_new_method_call(
                         bus,
+                        &m,
                         "org.freedesktop.systemd1",
                         "/org/freedesktop/systemd1",
                         "org.freedesktop.systemd1.Manager",
-                        method,
-                        error,
-                        &reply,
-                        "ss", name, mode);
+                        method);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_append(m, "ss", name, mode);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_call(bus, m, 0, error, &reply);
         if (r < 0) {
                 const char *verb;
 
@@ -2704,7 +2769,7 @@
 static int start_unit(sd_bus *bus, char **args) {
         _cleanup_set_free_free_ Set *s = NULL;
         _cleanup_strv_free_ char **names = NULL;
-        const char *method, *mode, *one_name;
+        const char *method, *mode, *one_name, *suffix = NULL;
         char **name;
         int r = 0;
 
@@ -2717,8 +2782,11 @@
                 method = verb_to_method(args[0]);
                 action = verb_to_action(args[0]);
 
-                mode = streq(args[0], "isolate") ? "isolate" :
-                       action_table[action].mode ?: arg_job_mode;
+                if (streq(args[0], "isolate")) {
+                        mode = "isolate";
+                        suffix = ".target";
+                } else
+                        mode = action_table[action].mode ?: arg_job_mode;
 
                 one_name = action_table[action].target;
         } else {
@@ -2734,7 +2802,7 @@
         if (one_name)
                 names = strv_new(one_name, NULL);
         else {
-                r = expand_names(bus, args + 1, NULL, &names);
+                r = expand_names(bus, args + 1, suffix, &names);
                 if (r < 0)
                         log_error("Failed to expand names: %s", strerror(-r));
         }
@@ -2824,7 +2892,7 @@
                         method,
                         &error,
                         NULL,
-                        "b", true);
+                        "b", arg_ask_password);
         if (r < 0)
                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
 
@@ -3047,18 +3115,29 @@
                 log_error("Failed to expand names: %s", strerror(-r));
 
         STRV_FOREACH(name, names) {
-                q = sd_bus_call_method(
+                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+
+                q = sd_bus_message_new_method_call(
                                 bus,
+                                &m,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "KillUnit",
-                                &error,
-                                NULL,
-                                "ssi", *names, arg_kill_who, arg_signal);
+                                "KillUnit");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_call(bus, m, 0, &error, NULL);
                 if (q < 0) {
-                        log_error("Failed to kill unit %s: %s",
-                                  *names, bus_error_message(&error, r));
+                        log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
                         if (r == 0)
                                 r = q;
                 }
@@ -4558,6 +4637,10 @@
         if (r < 0)
                 return bus_log_create_error(r);
 
+        r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+        if (r < 0)
+                return bus_log_create_error(r);
+
         n = unit_name_mangle(args[1], MANGLE_NOGLOB);
         if (!n)
                 return log_oom();
@@ -4599,7 +4682,7 @@
 
 static int snapshot(sd_bus *bus, char **args) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
         _cleanup_free_ char *n = NULL, *id = NULL;
         const char *path;
         int r;
@@ -4611,15 +4694,25 @@
         if (!n)
                 return log_oom();
 
-        r = sd_bus_call_method(
+        r = sd_bus_message_new_method_call(
                         bus,
+                        &m,
                         "org.freedesktop.systemd1",
                         "/org/freedesktop/systemd1",
                         "org.freedesktop.systemd1.Manager",
-                        "CreateSnapshot",
-                        &error,
-                        &reply,
-                        "sb", n, false);
+                        "CreateSnapshot");
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_append(m, "sb", n, false);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_call(bus, m, 0, &error, &reply);
         if (r < 0) {
                 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
                 return r;
@@ -4652,7 +4745,7 @@
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_strv_free_ char **names = NULL;
         char **name;
-        int r, q;
+        int r;
 
         assert(args);
 
@@ -4661,18 +4754,30 @@
                 log_error("Failed to expand names: %s", strerror(-r));
 
         STRV_FOREACH(name, names) {
-                q = sd_bus_call_method(
+                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+                int q;
+
+                q = sd_bus_message_new_method_call(
                                 bus,
+                                &m,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "RemoveSnapshot",
-                                &error,
-                                NULL,
-                                "s", *name);
+                                "RemoveSnapshot");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_append(m, "s", *name);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_call(bus, m, 0, &error, NULL);
                 if (q < 0) {
-                        log_error("Failed to remove snapshot %s: %s",
-                                  *name, bus_error_message(&error, r));
+                        log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
                         if (r == 0)
                                 r = q;
                 }
@@ -4683,6 +4788,7 @@
 
 static int daemon_reload(sd_bus *bus, char **args) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         const char *method;
         int r;
 
@@ -4706,16 +4812,21 @@
                                     /* "daemon-reload" */ "Reload";
         }
 
-        r = sd_bus_call_method(
+        r = sd_bus_message_new_method_call(
                         bus,
+                        &m,
                         "org.freedesktop.systemd1",
                         "/org/freedesktop/systemd1",
                         "org.freedesktop.systemd1.Manager",
-                        method,
-                        &error,
-                        NULL,
-                        NULL);
+                        method);
+        if (r < 0)
+                return bus_log_create_error(r);
 
+        r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_call(bus, m, 0, &error, NULL);
         if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
                 /* There's always a fallback possible for
                  * legacy actions. */
@@ -4744,18 +4855,29 @@
                 log_error("Failed to expand names: %s", strerror(-r));
 
         STRV_FOREACH(name, names) {
-                q = sd_bus_call_method(
+                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+
+                q = sd_bus_message_new_method_call(
                                 bus,
+                                &m,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "ResetFailedUnit",
-                                &error,
-                                NULL,
-                                "s", *name);
+                                "ResetFailedUnit");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_append(m, "s", *name);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_call(bus, m, 0, &error, NULL);
                 if (q < 0) {
-                        log_error("Failed to reset failed state of unit %s: %s",
-                                  *name, bus_error_message(&error, r));
+                        log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
                         if (r == 0)
                                 r = q;
                 }
@@ -4886,6 +5008,10 @@
         if (r < 0)
                 return bus_log_create_error(r);
 
+        r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+        if (r < 0)
+                return bus_log_create_error(r);
+
         r = sd_bus_message_append_strv(m, args + 1);
         if (r < 0)
                 return bus_log_create_error(r);
@@ -4917,6 +5043,10 @@
         if (r < 0)
                 return bus_log_create_error(r);
 
+        r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+        if (r < 0)
+                return bus_log_create_error(r);
+
         if (strv_isempty(args + 1))
                 r = sd_bus_message_append_strv(m, environ);
         else {
@@ -5228,6 +5358,10 @@
                 if (r < 0)
                         return bus_log_create_error(r);
 
+                r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
                 r = sd_bus_message_append_strv(m, names);
                 if (r < 0)
                         return bus_log_create_error(r);
@@ -5343,23 +5477,15 @@
                 if (r < 0)
                         return bus_log_create_error(r);
 
-                r = sd_bus_message_append_strv(m, names);
+                r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
                 if (r < 0)
                         return bus_log_create_error(r);
 
-                r = sd_bus_message_append(m, "s", target);
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                r = sd_bus_message_append(m, "s", unit_dependency_to_string(dep));
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                r = sd_bus_message_append(m, "b", arg_runtime);
+                r = sd_bus_message_append_strv(m, names);
                 if (r < 0)
                         return bus_log_create_error(r);
 
-                r = sd_bus_message_append(m, "b", arg_force);
+                r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
                 if (r < 0)
                         return bus_log_create_error(r);
 
@@ -5401,21 +5527,33 @@
                 r = 0;
 
         } else {
-                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+                _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
 
-                r = sd_bus_call_method(
+                r = sd_bus_message_new_method_call(
                                 bus,
+                                &m,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "PresetAllUnitFiles",
-                                &error,
-                                &reply,
+                                "PresetAllUnitFiles");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append(
+                                m,
                                 "sbb",
                                 unit_file_preset_mode_to_string(arg_preset_mode),
                                 arg_runtime,
                                 arg_force);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_call(bus, m, 0, &error, &reply);
                 if (r < 0) {
                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
                         return r;
diff -urN systemd-216/src/systemd/sd-bus.h systemd-217/src/systemd/sd-bus.h
--- systemd-216/src/systemd/sd-bus.h	2014-11-03 09:35:22.494121708 -0800
+++ systemd-217/src/systemd/sd-bus.h	2014-10-22 11:30:06.647837628 -0700
@@ -131,7 +131,7 @@
 int sd_bus_is_open(sd_bus *bus);
 int sd_bus_can_send(sd_bus *bus, char type);
 int sd_bus_get_server_id(sd_bus *bus, sd_id128_t *peer);
-int sd_bus_get_peer_creds(sd_bus *bus, uint64_t creds_mask, sd_bus_creds **ret);
+int sd_bus_get_owner_creds(sd_bus *bus, uint64_t creds_mask, sd_bus_creds **ret);
 int sd_bus_get_name(sd_bus *bus, const char **name);
 int sd_bus_get_tid(sd_bus *bus, pid_t *tid);
 
@@ -195,9 +195,11 @@
 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type);
 int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie);
 int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie);
+int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority);
+
 int sd_bus_message_get_expect_reply(sd_bus_message *m);
 int sd_bus_message_get_auto_start(sd_bus_message *m);
-int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority);
+int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m);
 
 const char *sd_bus_message_get_signature(sd_bus_message *m, int complete);
 const char *sd_bus_message_get_path(sd_bus_message *m);
@@ -221,6 +223,8 @@
 
 int sd_bus_message_set_expect_reply(sd_bus_message *m, int b);
 int sd_bus_message_set_auto_start(sd_bus_message *m, int b);
+int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b);
+
 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination);
 int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority);
 
@@ -256,8 +260,8 @@
 int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags);
 int sd_bus_release_name(sd_bus *bus, const char *name);
 int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable); /* free the results */
-int sd_bus_get_owner(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **creds); /* unref the result! */
-int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine);
+int sd_bus_get_name_creds(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **creds); /* unref the result! */
+int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine);
 
 /* Convenience calls */
 
diff -urN systemd-216/src/systemd/sd-bus-protocol.h systemd-217/src/systemd/sd-bus-protocol.h
--- systemd-216/src/systemd/sd-bus-protocol.h	2014-02-12 18:42:34.540682105 -0800
+++ systemd-217/src/systemd/sd-bus-protocol.h	2014-10-28 06:53:56.230977459 -0700
@@ -96,6 +96,8 @@
 #define SD_BUS_ERROR_INCONSISTENT_MESSAGE       "org.freedesktop.DBus.Error.InconsistentMessage"
 #define SD_BUS_ERROR_MATCH_RULE_NOT_FOUND       "org.freedesktop.DBus.Error.MatchRuleNotFound"
 #define SD_BUS_ERROR_MATCH_RULE_INVALID         "org.freedesktop.DBus.Error.MatchRuleInvalid"
+#define SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED \
+                                                "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired"
 
 _SD_END_DECLARATIONS;
 
diff -urN systemd-216/src/systemd/sd-dhcp6-client.h systemd-217/src/systemd/sd-dhcp6-client.h
--- systemd-216/src/systemd/sd-dhcp6-client.h	2014-11-03 09:35:33.807235778 -0800
+++ systemd-217/src/systemd/sd-dhcp6-client.h	2014-10-13 08:19:31.026675574 -0700
@@ -43,8 +43,8 @@
                                  sd_dhcp6_client_cb_t cb, void *userdata);
 
 int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index);
-int sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
-                            const struct ether_addr *mac_addr);
+int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr,
+                            size_t addr_len, uint16_t arp_type);
 int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *duid,
                              size_t duid_len);
 int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
diff -urN systemd-216/src/systemd/sd-dhcp-client.h systemd-217/src/systemd/sd-dhcp-client.h
--- systemd-216/src/systemd/sd-dhcp-client.h	2014-08-01 09:46:39.320201114 -0700
+++ systemd-217/src/systemd/sd-dhcp-client.h	2014-10-13 08:19:31.026675574 -0700
@@ -49,8 +49,8 @@
                                        const struct in_addr *last_address);
 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast);
 int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index);
-int sd_dhcp_client_set_mac(sd_dhcp_client *client,
-                           const struct ether_addr *addr);
+int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
+                           size_t addr_len, uint16_t arp_type);
 int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu);
 int sd_dhcp_client_set_hostname(sd_dhcp_client *client, const char *hostname);
 int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client, const char *vci);
diff -urN systemd-216/src/systemd/sd-login.h systemd-217/src/systemd/sd-login.h
--- systemd-216/src/systemd/sd-login.h	2014-11-03 09:35:30.992207394 -0800
+++ systemd-217/src/systemd/sd-login.h	2014-10-28 04:27:00.407284315 -0700
@@ -147,7 +147,7 @@
 /* Determine the class of this session, i.e. one of "user", "greeter" or "lock-screen". */
 int sd_session_get_class(const char *session, char **clazz);
 
-/* Determine the desktop brand of this session, i.e. something like "GNOME", "KDE" or "SYSTEMD-CONSOLE". */
+/* Determine the desktop brand of this session, i.e. something like "GNOME", "KDE" or "systemd-console". */
 int sd_session_get_desktop(const char *session, char **desktop);
 
 /* Determine the X11 display of this session. */
diff -urN systemd-216/src/systemd/sd-network.h systemd-217/src/systemd/sd-network.h
--- systemd-216/src/systemd/sd-network.h	2014-11-03 09:35:26.210159177 -0800
+++ systemd-217/src/systemd/sd-network.h	2014-10-22 07:38:35.338968963 -0700
@@ -61,7 +61,7 @@
 int sd_network_get_dns(char ***dns);
 
 /* Get NTP entries for all links. These are domain names or string
- * reperesentations of IP addresses */
+ * representations of IP addresses */
 int sd_network_get_ntp(char ***ntp);
 
 /* Get the search/routing domains for all links. */
@@ -80,7 +80,7 @@
  */
 int sd_network_link_get_setup_state(int ifindex, char **state);
 
-/* Get operatinal state from ifindex.
+/* Get operational state from ifindex.
  * Possible states:
  *   off: the device is powered down
  *   no-carrier: the device is powered up, but it does not yet have a carrier
@@ -101,13 +101,14 @@
 int sd_network_link_get_dns(int ifindex, char ***addr);
 
 /* Get NTP entries for a given link. These are domain names or string
- * reperesentations of IP addresses */
+ * representations of IP addresses */
 int sd_network_link_get_ntp(int ifindex, char ***addr);
 
 /* Indicates whether or not LLMNR should be enabled for the link
  * Possible levels of support: yes, no, resolve
  * Possible return codes:
- *   -ENODATA: networkd is not aware of the link*/
+ *   -ENODATA: networkd is not aware of the link
+ */
 int sd_network_link_get_llmnr(int ifindex, char **llmnr);
 
 /* Get the DNS domain names for a given link. */
diff -urN systemd-216/src/sysusers/sysusers.c systemd-217/src/sysusers/sysusers.c
--- systemd-216/src/sysusers/sysusers.c	2014-11-03 09:35:29.560192955 -0800
+++ systemd-217/src/sysusers/sysusers.c	2014-11-03 09:33:48.821177204 -0800
@@ -358,6 +358,7 @@
         _cleanup_fclose_ FILE *passwd = NULL, *group = NULL, *shadow = NULL, *gshadow = NULL;
         _cleanup_free_ char *passwd_tmp = NULL, *group_tmp = NULL, *shadow_tmp = NULL, *gshadow_tmp = NULL;
         const char *passwd_path = NULL, *group_path = NULL, *shadow_path = NULL, *gshadow_path = NULL;
+        struct stat st;
         bool group_changed = false;
         Iterator iterator;
         Item *i;
@@ -372,15 +373,17 @@
                 if (r < 0)
                         goto finish;
 
-                if (fchmod(fileno(group), 0644) < 0) {
-                        r = -errno;
-                        goto finish;
-                }
-
                 original = fopen(group_path, "re");
                 if (original) {
                         struct group *gr;
 
+                        if (fstat(fileno(original), &st) < 0 ||
+                            fchmod(fileno(group), st.st_mode & 07777) < 0 ||
+                            fchown(fileno(group), st.st_uid, st.st_gid) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+
                         errno = 0;
                         while ((gr = fgetgrent(original))) {
                                 /* Safety checks against name and GID
@@ -418,6 +421,9 @@
                 } else if (errno != ENOENT) {
                         r = -errno;
                         goto finish;
+                } else if (fchmod(fileno(group), 0644) < 0) {
+                        r = -errno;
+                        goto finish;
                 }
 
                 HASHMAP_FOREACH(i, todo_gids, iterator) {
@@ -449,15 +455,17 @@
                 if (r < 0)
                         goto finish;
 
-                if (fchmod(fileno(gshadow), 0000) < 0) {
-                        r = -errno;
-                        goto finish;
-                }
-
                 original = fopen(gshadow_path, "re");
                 if (original) {
                         struct sgrp *sg;
 
+                        if (fstat(fileno(original), &st) < 0 ||
+                            fchmod(fileno(gshadow), st.st_mode & 07777) < 0 ||
+                            fchown(fileno(gshadow), st.st_uid, st.st_gid) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+
                         errno = 0;
                         while ((sg = fgetsgent(original))) {
 
@@ -483,6 +491,9 @@
                 } else if (errno != ENOENT) {
                         r = -errno;
                         goto finish;
+                } else if (fchmod(fileno(gshadow), 0000) < 0) {
+                        r = -errno;
+                        goto finish;
                 }
 
                 HASHMAP_FOREACH(i, todo_gids, iterator) {
@@ -513,15 +524,17 @@
                 if (r < 0)
                         goto finish;
 
-                if (fchmod(fileno(passwd), 0644) < 0) {
-                        r = -errno;
-                        goto finish;
-                }
-
                 original = fopen(passwd_path, "re");
                 if (original) {
                         struct passwd *pw;
 
+                        if (fstat(fileno(original), &st) < 0 ||
+                            fchmod(fileno(passwd), st.st_mode & 07777) < 0 ||
+                            fchown(fileno(passwd), st.st_uid, st.st_gid) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+
                         errno = 0;
                         while ((pw = fgetpwent(original))) {
 
@@ -552,6 +565,9 @@
                 } else if (errno != ENOENT) {
                         r = -errno;
                         goto finish;
+                } else if (fchmod(fileno(passwd), 0644) < 0) {
+                        r = -errno;
+                        goto finish;
                 }
 
                 HASHMAP_FOREACH(i, todo_uids, iterator) {
@@ -596,15 +612,17 @@
                 if (r < 0)
                         goto finish;
 
-                if (fchmod(fileno(shadow), 0000) < 0) {
-                        r = -errno;
-                        goto finish;
-                }
-
                 original = fopen(shadow_path, "re");
                 if (original) {
                         struct spwd *sp;
 
+                        if (fstat(fileno(original), &st) < 0 ||
+                            fchmod(fileno(shadow), st.st_mode & 07777) < 0 ||
+                            fchown(fileno(shadow), st.st_uid, st.st_gid) < 0) {
+                                r = -errno;
+                                goto finish;
+                        }
+
                         errno = 0;
                         while ((sp = fgetspent(original))) {
 
@@ -629,6 +647,9 @@
                 } else if (errno != ENOENT) {
                         r = -errno;
                         goto finish;
+                } else if (fchmod(fileno(shadow), 0000) < 0) {
+                        r = -errno;
+                        goto finish;
                 }
 
                 lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
@@ -1835,7 +1856,7 @@
 
         umask(0022);
 
-        r = label_init(NULL);
+        r = mac_selinux_init(NULL);
         if (r < 0) {
                 log_error("SELinux setup failed: %s", strerror(-r));
                 goto finish;
diff -urN systemd-216/src/test/test-calendarspec.c systemd-217/src/test/test-calendarspec.c
--- systemd-216/src/test/test-calendarspec.c	2014-03-18 10:05:50.560378058 -0700
+++ systemd-217/src/test/test-calendarspec.c	2014-10-27 10:09:26.683861816 -0700
@@ -77,6 +77,10 @@
         test_one("daily", "*-*-* 00:00:00");
         test_one("monthly", "*-*-01 00:00:00");
         test_one("weekly", "Mon *-*-* 00:00:00");
+        test_one("minutely", "*-*-* *:*:00");
+        test_one("quarterly", "*-01,04,07,10-01 00:00:00");
+        test_one("semi-annually", "*-01,07-01 00:00:00");
+        test_one("annually", "*-01-01 00:00:00");
         test_one("*:2/3", "*-*-* *:02/3:00");
 
         assert_se(calendar_spec_from_string("test", &c) < 0);
diff -urN systemd-216/src/test/test-engine.c systemd-217/src/test/test-engine.c
--- systemd-216/src/test/test-engine.c	2014-11-03 09:35:35.118248997 -0800
+++ systemd-217/src/test/test-engine.c	2014-10-13 08:19:31.026675574 -0700
@@ -39,7 +39,7 @@
         /* prepare the test */
         assert_se(set_unit_path(TEST_DIR) >= 0);
         r = manager_new(SYSTEMD_USER, true, &m);
-        if (r == -EPERM || r == -EACCES || r == -EADDRINUSE || r == -EHOSTDOWN) {
+        if (IN_SET(r, -EPERM, -EACCES, -EADDRINUSE, -EHOSTDOWN, -ENOENT)) {
                 printf("Skipping test: manager_new: %s", strerror(-r));
                 return EXIT_TEST_SKIP;
         }
diff -urN systemd-216/src/test/test-fileio.c systemd-217/src/test/test-fileio.c
--- systemd-216/src/test/test-fileio.c	2014-11-03 09:35:35.118248997 -0800
+++ systemd-217/src/test/test-fileio.c	2014-10-20 10:23:13.444878955 -0700
@@ -90,7 +90,7 @@
         assert_se(streq_ptr(a[9], "ten="));
         assert_se(a[10] == NULL);
 
-        strv_env_clean_log(a, "test");
+        strv_env_clean_log(a, NULL, "test");
 
         k = 0;
         STRV_FOREACH(i, b) {
diff -urN systemd-216/src/test/test-hashmap.c systemd-217/src/test/test-hashmap.c
--- systemd-216/src/test/test-hashmap.c	2014-11-03 09:35:35.118248997 -0800
+++ systemd-217/src/test/test-hashmap.c	2014-10-23 10:00:37.308180914 -0700
@@ -22,116 +22,14 @@
 #include "util.h"
 #include "hashmap.h"
 
-static void test_hashmap_replace(void) {
-        Hashmap *m;
-        char *val1, *val2, *val3, *val4, *val5, *r;
+void test_hashmap_funcs(void);
+void test_ordered_hashmap_funcs(void);
 
-        m = hashmap_new(&string_hash_ops);
-
-        val1 = strdup("val1");
-        assert_se(val1);
-        val2 = strdup("val2");
-        assert_se(val2);
-        val3 = strdup("val3");
-        assert_se(val3);
-        val4 = strdup("val4");
-        assert_se(val4);
-        val5 = strdup("val5");
-        assert_se(val5);
-
-        hashmap_put(m, "key 1", val1);
-        hashmap_put(m, "key 2", val2);
-        hashmap_put(m, "key 3", val3);
-        hashmap_put(m, "key 4", val4);
-
-        hashmap_replace(m, "key 3", val1);
-        r = hashmap_get(m, "key 3");
-        assert_se(streq(r, "val1"));
-
-        hashmap_replace(m, "key 5", val5);
-        r = hashmap_get(m, "key 5");
-        assert_se(streq(r, "val5"));
-
-        free(val1);
-        free(val2);
-        free(val3);
-        free(val4);
-        free(val5);
-        hashmap_free(m);
-}
-
-static void test_hashmap_copy(void) {
-        Hashmap *m, *copy;
-        char *val1, *val2, *val3, *val4, *r;
-
-        val1 = strdup("val1");
-        assert_se(val1);
-        val2 = strdup("val2");
-        assert_se(val2);
-        val3 = strdup("val3");
-        assert_se(val3);
-        val4 = strdup("val4");
-        assert_se(val4);
-
-        m = hashmap_new(&string_hash_ops);
-
-        hashmap_put(m, "key 1", val1);
-        hashmap_put(m, "key 2", val2);
-        hashmap_put(m, "key 3", val3);
-        hashmap_put(m, "key 4", val4);
-
-        copy = hashmap_copy(m);
-
-        r = hashmap_get(copy, "key 1");
-        assert_se(streq(r, "val1"));
-        r = hashmap_get(copy, "key 2");
-        assert_se(streq(r, "val2"));
-        r = hashmap_get(copy, "key 3");
-        assert_se(streq(r, "val3"));
-        r = hashmap_get(copy, "key 4");
-        assert_se(streq(r, "val4"));
-
-        hashmap_free_free(copy);
-        hashmap_free(m);
-}
-
-static void test_hashmap_get_strv(void) {
-        Hashmap *m;
-        char **strv;
-        char *val1, *val2, *val3, *val4;
-
-        val1 = strdup("val1");
-        assert_se(val1);
-        val2 = strdup("val2");
-        assert_se(val2);
-        val3 = strdup("val3");
-        assert_se(val3);
-        val4 = strdup("val4");
-        assert_se(val4);
-
-        m = hashmap_new(&string_hash_ops);
-
-        hashmap_put(m, "key 1", val1);
-        hashmap_put(m, "key 2", val2);
-        hashmap_put(m, "key 3", val3);
-        hashmap_put(m, "key 4", val4);
-
-        strv = hashmap_get_strv(m);
-
-        assert_se(streq(strv[0], "val1"));
-        assert_se(streq(strv[1], "val2"));
-        assert_se(streq(strv[2], "val3"));
-        assert_se(streq(strv[3], "val4"));
-
-        strv_free(strv);
-
-        hashmap_free(m);
-}
-
-static void test_hashmap_move_one(void) {
-        Hashmap *m, *n;
+static void test_ordered_hashmap_next(void) {
+        OrderedHashmap *m;
         char *val1, *val2, *val3, *val4, *r;
 
+        m = ordered_hashmap_new(&string_hash_ops);
         val1 = strdup("val1");
         assert_se(val1);
         val2 = strdup("val2");
@@ -141,404 +39,25 @@
         val4 = strdup("val4");
         assert_se(val4);
 
-        m = hashmap_new(&string_hash_ops);
-        n = hashmap_new(&string_hash_ops);
-
-        hashmap_put(m, "key 1", val1);
-        hashmap_put(m, "key 2", val2);
-        hashmap_put(m, "key 3", val3);
-        hashmap_put(m, "key 4", val4);
-
-        hashmap_move_one(n, m, "key 3");
-        hashmap_move_one(n, m, "key 4");
-
-        r = hashmap_get(n, "key 3");
-        assert_se(r && streq(r, "val3"));
-        r = hashmap_get(n, "key 4");
-        assert_se(r && streq(r, "val4"));
-        r = hashmap_get(m, "key 3");
-        assert_se(!r);
-
+        ordered_hashmap_put(m, "key 1", val1);
+        ordered_hashmap_put(m, "key 2", val2);
+        ordered_hashmap_put(m, "key 3", val3);
+        ordered_hashmap_put(m, "key 4", val4);
 
-        hashmap_free_free(m);
-        hashmap_free_free(n);
-}
-
-static void test_hashmap_next(void) {
-        Hashmap *m;
-        char *val1, *val2, *val3, *val4, *r;
-
-        m = hashmap_new(&string_hash_ops);
-        val1 = strdup("val1");
-        assert_se(val1);
-        val2 = strdup("val2");
-        assert_se(val2);
-        val3 = strdup("val3");
-        assert_se(val3);
-        val4 = strdup("val4");
-        assert_se(val4);
-
-        hashmap_put(m, "key 1", val1);
-        hashmap_put(m, "key 2", val2);
-        hashmap_put(m, "key 3", val3);
-        hashmap_put(m, "key 4", val4);
-
-        r = hashmap_next(m, "key 1");
+        r = ordered_hashmap_next(m, "key 1");
         assert_se(streq(r, val2));
-        r = hashmap_next(m, "key 2");
+        r = ordered_hashmap_next(m, "key 2");
         assert_se(streq(r, val3));
-        r = hashmap_next(m, "key 3");
+        r = ordered_hashmap_next(m, "key 3");
         assert_se(streq(r, val4));
-        r = hashmap_next(m, "key 4");
+        r = ordered_hashmap_next(m, "key 4");
+        assert_se(!r);
+        r = ordered_hashmap_next(NULL, "key 1");
+        assert_se(!r);
+        r = ordered_hashmap_next(m, "key 5");
         assert_se(!r);
 
-        hashmap_free_free(m);
-}
-
-static void test_hashmap_update(void) {
-        Hashmap *m;
-        char *val1, *val2, *r;
-
-        m = hashmap_new(&string_hash_ops);
-        val1 = strdup("old_value");
-        assert_se(val1);
-        val2 = strdup("new_value");
-        assert_se(val2);
-
-        hashmap_put(m, "key 1", val1);
-        r = hashmap_get(m, "key 1");
-        assert_se(streq(r, "old_value"));
-
-        hashmap_update(m, "key 1", val2);
-        r = hashmap_get(m, "key 1");
-        assert_se(streq(r, "new_value"));
-
-        free(val1);
-        free(val2);
-        hashmap_free(m);
-}
-
-static void test_hashmap_put(void) {
-        Hashmap *m;
-        int valid_hashmap_put;
-
-        m = hashmap_new(&string_hash_ops);
-
-        valid_hashmap_put = hashmap_put(m, "key 1", (void*) (const char *) "val 1");
-        assert_se(valid_hashmap_put == 1);
-
-        assert_se(m);
-        hashmap_free(m);
-}
-
-static void test_hashmap_remove_and_put(void) {
-        _cleanup_hashmap_free_ Hashmap *m = NULL;
-        int valid;
-        char *r;
-
-        m = hashmap_new(&string_hash_ops);
-        assert_se(m);
-
-        valid = hashmap_remove_and_put(m, "unvalid key", "new key", NULL);
-        assert_se(valid < 0);
-
-        valid = hashmap_put(m, "key 1", (void*) (const char *) "val 1");
-        assert_se(valid == 1);
-        valid = hashmap_remove_and_put(m, "key 1", "key 2", (void*) (const char *) "val 2");
-        assert_se(valid == 0);
-
-        r = hashmap_get(m, "key 2");
-        assert_se(streq(r, "val 2"));
-        assert_se(!hashmap_get(m, "key 1"));
-
-        valid = hashmap_put(m, "key 3", (void*) (const char *) "val 3");
-        assert_se(valid == 1);
-        valid = hashmap_remove_and_put(m, "key 3", "key 2", (void*) (const char *) "val 2");
-        assert_se(valid < 0);
-}
-
-static void test_hashmap_ensure_allocated(void) {
-        Hashmap *m;
-        int valid_hashmap;
-
-        m = hashmap_new(&string_hash_ops);
-
-        valid_hashmap = hashmap_ensure_allocated(&m, &string_hash_ops);
-        assert_se(valid_hashmap == 0);
-
-        assert_se(m);
-        hashmap_free(m);
-}
-
-static void test_hashmap_foreach_key(void) {
-        Hashmap *m;
-        Iterator i;
-        bool key_found[] = { false, false, false, false };
-        const char *s;
-        const char *key;
-        static const char key_table[] =
-                "key 1\0"
-                "key 2\0"
-                "key 3\0"
-                "key 4\0";
-
-        m = hashmap_new(&string_hash_ops);
-
-        NULSTR_FOREACH(key, key_table)
-                hashmap_put(m, key, (void*) (const char*) "my dummy val");
-
-        HASHMAP_FOREACH_KEY(s, key, m, i) {
-                if (!key_found[0] && streq(key, "key 1"))
-                        key_found[0] = true;
-                else if (!key_found[1] && streq(key, "key 2"))
-                        key_found[1] = true;
-                else if (!key_found[2] && streq(key, "key 3"))
-                        key_found[2] = true;
-                else if (!key_found[3] && streq(key, "fail"))
-                        key_found[3] = true;
-        }
-
-        assert_se(m);
-        assert_se(key_found[0] && key_found[1] && key_found[2] && !key_found[3]);
-
-        hashmap_free(m);
-}
-
-static void test_hashmap_foreach(void) {
-        Hashmap *m;
-        Iterator i;
-        bool value_found[] = { false, false, false, false };
-        char *val1, *val2, *val3, *val4, *s;
-
-        val1 = strdup("my val1");
-        assert_se(val1);
-        val2 = strdup("my val2");
-        assert_se(val2);
-        val3 = strdup("my val3");
-        assert_se(val3);
-        val4 = strdup("my val4");
-        assert_se(val4);
-
-        m = hashmap_new(&string_hash_ops);
-
-        hashmap_put(m, "Key 1", val1);
-        hashmap_put(m, "Key 2", val2);
-        hashmap_put(m, "Key 3", val3);
-        hashmap_put(m, "Key 4", val4);
-
-        HASHMAP_FOREACH(s, m, i) {
-                if (!value_found[0] && streq(s, val1))
-                        value_found[0] = true;
-                else if (!value_found[1] && streq(s, val2))
-                        value_found[1] = true;
-                else if (!value_found[2] && streq(s, val3))
-                        value_found[2] = true;
-                else if (!value_found[3] && streq(s, val4))
-                        value_found[3] = true;
-        }
-
-        assert_se(m);
-        assert_se(value_found[0] && value_found[1] && value_found[2] && value_found[3]);
-
-        hashmap_free_free(m);
-}
-
-static void test_hashmap_merge(void) {
-        Hashmap *m;
-        Hashmap *n;
-        char *val1, *val2, *val3, *val4, *r;
-
-        val1 = strdup("my val1");
-        assert_se(val1);
-        val2 = strdup("my val2");
-        assert_se(val2);
-        val3 = strdup("my val3");
-        assert_se(val3);
-        val4 = strdup("my val4");
-        assert_se(val4);
-
-        n = hashmap_new(&string_hash_ops);
-        m = hashmap_new(&string_hash_ops);
-
-        hashmap_put(m, "Key 1", val1);
-        hashmap_put(m, "Key 2", val2);
-        hashmap_put(n, "Key 3", val3);
-        hashmap_put(n, "Key 4", val4);
-
-        assert_se(hashmap_merge(m, n) == 0);
-        r = hashmap_get(m, "Key 3");
-        assert_se(r && streq(r, "my val3"));
-        r = hashmap_get(m, "Key 4");
-        assert_se(r && streq(r, "my val4"));
-
-        assert_se(n);
-        assert_se(m);
-        hashmap_free(n);
-        hashmap_free_free(m);
-}
-
-static void test_hashmap_contains(void) {
-        Hashmap *m;
-        char *val1;
-
-        val1 = strdup("my val");
-        assert_se(val1);
-
-        m = hashmap_new(&string_hash_ops);
-
-        assert_se(!hashmap_contains(m, "Key 1"));
-        hashmap_put(m, "Key 1", val1);
-        assert_se(hashmap_contains(m, "Key 1"));
-
-        assert_se(m);
-        hashmap_free_free(m);
-}
-
-static void test_hashmap_isempty(void) {
-        Hashmap *m;
-        char *val1;
-
-        val1 = strdup("my val");
-        assert_se(val1);
-
-        m = hashmap_new(&string_hash_ops);
-
-        assert_se(hashmap_isempty(m));
-        hashmap_put(m, "Key 1", val1);
-        assert_se(!hashmap_isempty(m));
-
-        assert_se(m);
-        hashmap_free_free(m);
-}
-
-static void test_hashmap_size(void) {
-        Hashmap *m;
-        char *val1, *val2, *val3, *val4;
-
-        val1 = strdup("my val");
-        assert_se(val1);
-        val2 = strdup("my val");
-        assert_se(val2);
-        val3 = strdup("my val");
-        assert_se(val3);
-        val4 = strdup("my val");
-        assert_se(val4);
-
-        m = hashmap_new(&string_hash_ops);
-
-        hashmap_put(m, "Key 1", val1);
-        hashmap_put(m, "Key 2", val2);
-        hashmap_put(m, "Key 3", val3);
-        hashmap_put(m, "Key 4", val4);
-
-        assert_se(m);
-        assert_se(hashmap_size(m) == 4);
-        hashmap_free_free(m);
-}
-
-static void test_hashmap_get(void) {
-        Hashmap *m;
-        char *r;
-        char *val;
-
-        val = strdup("my val");
-        assert_se(val);
-
-        m = hashmap_new(&string_hash_ops);
-
-        hashmap_put(m, "Key 1", val);
-
-        r = hashmap_get(m, "Key 1");
-        assert_se(streq(r, val));
-
-        assert_se(m);
-        hashmap_free_free(m);
-}
-
-static void test_hashmap_many(void) {
-        Hashmap *h;
-        unsigned i;
-
-#define N_ENTRIES 100000
-
-        assert_se(h = hashmap_new(NULL));
-
-        for (i = 1; i < N_ENTRIES*3; i+=3) {
-                assert_se(hashmap_put(h, UINT_TO_PTR(i), UINT_TO_PTR(i)) >= 0);
-                assert_se(PTR_TO_UINT(hashmap_get(h, UINT_TO_PTR(i))) == i);
-        }
-
-        for (i = 1; i < N_ENTRIES*3; i++)
-                assert_se(hashmap_contains(h, UINT_TO_PTR(i)) == (i % 3 == 1));
-
-        log_info("%u <= %u * 0.75 = %g", hashmap_size(h), hashmap_buckets(h), hashmap_buckets(h) * 0.75);
-
-        assert_se(hashmap_size(h) <= hashmap_buckets(h) * 0.75);
-        assert_se(hashmap_size(h) == N_ENTRIES);
-
-        hashmap_free(h);
-}
-
-static void test_hashmap_first_key(void) {
-        _cleanup_hashmap_free_ Hashmap *m = NULL;
-
-        m = hashmap_new(&string_hash_ops);
-        assert_se(m);
-
-        assert_se(!hashmap_first_key(m));
-        assert_se(hashmap_put(m, "key 1", NULL) == 1);
-        assert_se(streq(hashmap_first_key(m), "key 1"));
-        assert_se(hashmap_put(m, "key 2", NULL) == 1);
-        assert_se(streq(hashmap_first_key(m), "key 1"));
-        assert_se(hashmap_remove(m, "key 1") == NULL);
-        assert_se(streq(hashmap_first_key(m), "key 2"));
-}
-
-static void test_hashmap_steal_first_key(void) {
-        _cleanup_hashmap_free_ Hashmap *m = NULL;
-
-        m = hashmap_new(&string_hash_ops);
-        assert_se(m);
-
-        assert_se(!hashmap_steal_first_key(m));
-        assert_se(hashmap_put(m, "key 1", NULL) == 1);
-        assert_se(streq(hashmap_steal_first_key(m), "key 1"));
-
-        assert_se(hashmap_isempty(m));
-}
-
-static void test_hashmap_steal_first(void) {
-        _cleanup_hashmap_free_ Hashmap *m = NULL;
-        int seen[3] = {};
-        char *val;
-
-        m = hashmap_new(&string_hash_ops);
-        assert_se(m);
-
-        assert_se(hashmap_put(m, "key 1", (void*) "1") == 1);
-        assert_se(hashmap_put(m, "key 2", (void*) "22") == 1);
-        assert_se(hashmap_put(m, "key 3", (void*) "333") == 1);
-
-        while ((val = hashmap_steal_first(m)))
-                seen[strlen(val) - 1]++;
-
-        assert_se(seen[0] == 1 && seen[1] == 1 && seen[2] == 1);
-
-        assert_se(hashmap_isempty(m));
-}
-
-static void test_hashmap_clear_free_free(void) {
-        _cleanup_hashmap_free_ Hashmap *m = NULL;
-
-        m = hashmap_new(&string_hash_ops);
-        assert_se(m);
-
-        assert_se(hashmap_put(m, strdup("key 1"), NULL) == 1);
-        assert_se(hashmap_put(m, strdup("key 2"), NULL) == 1);
-        assert_se(hashmap_put(m, strdup("key 3"), NULL) == 1);
-
-        hashmap_clear_free_free(m);
-        assert_se(hashmap_isempty(m));
+        ordered_hashmap_free_free(m);
 }
 
 static void test_uint64_compare_func(void) {
@@ -561,27 +80,10 @@
 }
 
 int main(int argc, const char *argv[]) {
-        test_hashmap_copy();
-        test_hashmap_get_strv();
-        test_hashmap_move_one();
-        test_hashmap_next();
-        test_hashmap_replace();
-        test_hashmap_update();
-        test_hashmap_put();
-        test_hashmap_remove_and_put();
-        test_hashmap_ensure_allocated();
-        test_hashmap_foreach();
-        test_hashmap_foreach_key();
-        test_hashmap_contains();
-        test_hashmap_merge();
-        test_hashmap_isempty();
-        test_hashmap_get();
-        test_hashmap_size();
-        test_hashmap_many();
-        test_hashmap_first_key();
-        test_hashmap_steal_first_key();
-        test_hashmap_steal_first();
-        test_hashmap_clear_free_free();
+        test_hashmap_funcs();
+        test_ordered_hashmap_funcs();
+
+        test_ordered_hashmap_next();
         test_uint64_compare_func();
         test_trivial_compare_func();
         test_string_compare_func();
diff -urN systemd-216/src/test/test-hashmap-plain.c systemd-217/src/test/test-hashmap-plain.c
--- systemd-216/src/test/test-hashmap-plain.c	1969-12-31 16:00:00.000000000 -0800
+++ systemd-217/src/test/test-hashmap-plain.c	2014-10-23 10:00:37.308180914 -0700
@@ -0,0 +1,844 @@
+/***
+  This file is part of systemd
+
+  Copyright 2013 Daniel Buch
+
+  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 "strv.h"
+#include "util.h"
+#include "hashmap.h"
+
+void test_hashmap_funcs(void);
+
+static void test_hashmap_replace(void) {
+        Hashmap *m;
+        char *val1, *val2, *val3, *val4, *val5, *r;
+
+        m = hashmap_new(&string_hash_ops);
+
+        val1 = strdup("val1");
+        assert_se(val1);
+        val2 = strdup("val2");
+        assert_se(val2);
+        val3 = strdup("val3");
+        assert_se(val3);
+        val4 = strdup("val4");
+        assert_se(val4);
+        val5 = strdup("val5");
+        assert_se(val5);
+
+        hashmap_put(m, "key 1", val1);
+        hashmap_put(m, "key 2", val2);
+        hashmap_put(m, "key 3", val3);
+        hashmap_put(m, "key 4", val4);
+
+        hashmap_replace(m, "key 3", val1);
+        r = hashmap_get(m, "key 3");
+        assert_se(streq(r, "val1"));
+
+        hashmap_replace(m, "key 5", val5);
+        r = hashmap_get(m, "key 5");
+        assert_se(streq(r, "val5"));
+
+        free(val1);
+        free(val2);
+        free(val3);
+        free(val4);
+        free(val5);
+        hashmap_free(m);
+}
+
+static void test_hashmap_copy(void) {
+        Hashmap *m, *copy;
+        char *val1, *val2, *val3, *val4, *r;
+
+        val1 = strdup("val1");
+        assert_se(val1);
+        val2 = strdup("val2");
+        assert_se(val2);
+        val3 = strdup("val3");
+        assert_se(val3);
+        val4 = strdup("val4");
+        assert_se(val4);
+
+        m = hashmap_new(&string_hash_ops);
+
+        hashmap_put(m, "key 1", val1);
+        hashmap_put(m, "key 2", val2);
+        hashmap_put(m, "key 3", val3);
+        hashmap_put(m, "key 4", val4);
+
+        copy = hashmap_copy(m);
+
+        r = hashmap_get(copy, "key 1");
+        assert_se(streq(r, "val1"));
+        r = hashmap_get(copy, "key 2");
+        assert_se(streq(r, "val2"));
+        r = hashmap_get(copy, "key 3");
+        assert_se(streq(r, "val3"));
+        r = hashmap_get(copy, "key 4");
+        assert_se(streq(r, "val4"));
+
+        hashmap_free_free(copy);
+        hashmap_free(m);
+}
+
+static void test_hashmap_get_strv(void) {
+        Hashmap *m;
+        char **strv;
+        char *val1, *val2, *val3, *val4;
+
+        val1 = strdup("val1");
+        assert_se(val1);
+        val2 = strdup("val2");
+        assert_se(val2);
+        val3 = strdup("val3");
+        assert_se(val3);
+        val4 = strdup("val4");
+        assert_se(val4);
+
+        m = hashmap_new(&string_hash_ops);
+
+        hashmap_put(m, "key 1", val1);
+        hashmap_put(m, "key 2", val2);
+        hashmap_put(m, "key 3", val3);
+        hashmap_put(m, "key 4", val4);
+
+        strv = hashmap_get_strv(m);
+
+#ifndef ORDERED
+        strv = strv_sort(strv);
+#endif
+
+        assert_se(streq(strv[0], "val1"));
+        assert_se(streq(strv[1], "val2"));
+        assert_se(streq(strv[2], "val3"));
+        assert_se(streq(strv[3], "val4"));
+
+        strv_free(strv);
+
+        hashmap_free(m);
+}
+
+static void test_hashmap_move_one(void) {
+        Hashmap *m, *n;
+        char *val1, *val2, *val3, *val4, *r;
+
+        val1 = strdup("val1");
+        assert_se(val1);
+        val2 = strdup("val2");
+        assert_se(val2);
+        val3 = strdup("val3");
+        assert_se(val3);
+        val4 = strdup("val4");
+        assert_se(val4);
+
+        m = hashmap_new(&string_hash_ops);
+        n = hashmap_new(&string_hash_ops);
+
+        hashmap_put(m, "key 1", val1);
+        hashmap_put(m, "key 2", val2);
+        hashmap_put(m, "key 3", val3);
+        hashmap_put(m, "key 4", val4);
+
+        assert_se(hashmap_move_one(n, NULL, "key 3") == -ENOENT);
+        assert_se(hashmap_move_one(n, m, "key 5") == -ENOENT);
+        assert_se(hashmap_move_one(n, m, "key 3") == 0);
+        assert_se(hashmap_move_one(n, m, "key 4") == 0);
+
+        r = hashmap_get(n, "key 3");
+        assert_se(r && streq(r, "val3"));
+        r = hashmap_get(n, "key 4");
+        assert_se(r && streq(r, "val4"));
+        r = hashmap_get(m, "key 3");
+        assert_se(!r);
+
+        assert_se(hashmap_move_one(n, m, "key 3") == -EEXIST);
+
+        hashmap_free_free(m);
+        hashmap_free_free(n);
+}
+
+static void test_hashmap_move(void) {
+        Hashmap *m, *n;
+        char *val1, *val2, *val3, *val4, *r;
+
+        val1 = strdup("val1");
+        assert_se(val1);
+        val2 = strdup("val2");
+        assert_se(val2);
+        val3 = strdup("val3");
+        assert_se(val3);
+        val4 = strdup("val4");
+        assert_se(val4);
+
+        m = hashmap_new(&string_hash_ops);
+        n = hashmap_new(&string_hash_ops);
+
+        hashmap_put(n, "key 1", strdup(val1));
+        hashmap_put(m, "key 1", val1);
+        hashmap_put(m, "key 2", val2);
+        hashmap_put(m, "key 3", val3);
+        hashmap_put(m, "key 4", val4);
+
+        assert(hashmap_move(n, NULL) == 0);
+        assert(hashmap_move(n, m) == 0);
+
+        assert_se(hashmap_size(m) == 1);
+        r = hashmap_get(m, "key 1");
+        assert_se(r && streq(r, "val1"));
+
+        r = hashmap_get(n, "key 1");
+        assert_se(r && streq(r, "val1"));
+        r = hashmap_get(n, "key 2");
+        assert_se(r && streq(r, "val2"));
+        r = hashmap_get(n, "key 3");
+        assert_se(r && streq(r, "val3"));
+        r = hashmap_get(n, "key 4");
+        assert_se(r && streq(r, "val4"));
+
+        hashmap_free_free(m);
+        hashmap_free_free(n);
+}
+
+static void test_hashmap_update(void) {
+        Hashmap *m;
+        char *val1, *val2, *r;
+
+        m = hashmap_new(&string_hash_ops);
+        val1 = strdup("old_value");
+        assert_se(val1);
+        val2 = strdup("new_value");
+        assert_se(val2);
+
+        hashmap_put(m, "key 1", val1);
+        r = hashmap_get(m, "key 1");
+        assert_se(streq(r, "old_value"));
+
+        assert_se(hashmap_update(m, "key 2", val2) == -ENOENT);
+        r = hashmap_get(m, "key 1");
+        assert_se(streq(r, "old_value"));
+
+        assert_se(hashmap_update(m, "key 1", val2) == 0);
+        r = hashmap_get(m, "key 1");
+        assert_se(streq(r, "new_value"));
+
+        free(val1);
+        free(val2);
+        hashmap_free(m);
+}
+
+static void test_hashmap_put(void) {
+        Hashmap *m = NULL;
+        int valid_hashmap_put;
+        void *val1 = (void*) "val 1";
+
+        hashmap_ensure_allocated(&m, &string_hash_ops);
+        assert_se(m);
+
+        valid_hashmap_put = hashmap_put(m, "key 1", val1);
+        assert_se(valid_hashmap_put == 1);
+        assert_se(hashmap_put(m, "key 1", val1) == 0);
+        assert_se(hashmap_put(m, "key 1", (void *)"val 2") == -EEXIST);
+
+        hashmap_free(m);
+}
+
+static void test_hashmap_remove(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+        char *r;
+
+        r = hashmap_remove(NULL, "key 1");
+        assert_se(r == NULL);
+
+        m = hashmap_new(&string_hash_ops);
+        assert_se(m);
+
+        r = hashmap_remove(m, "no such key");
+        assert_se(r == NULL);
+
+        hashmap_put(m, "key 1", (void*) "val 1");
+        hashmap_put(m, "key 2", (void*) "val 2");
+
+        r = hashmap_remove(m, "key 1");
+        assert_se(streq(r, "val 1"));
+
+        r = hashmap_get(m, "key 2");
+        assert_se(streq(r, "val 2"));
+        assert_se(!hashmap_get(m, "key 1"));
+}
+
+static void test_hashmap_remove2(void) {
+        _cleanup_hashmap_free_free_free_ Hashmap *m = NULL;
+        char key1[] = "key 1";
+        char key2[] = "key 2";
+        char val1[] = "val 1";
+        char val2[] = "val 2";
+        void *r, *r2;
+
+        r = hashmap_remove2(NULL, "key 1", &r2);
+        assert_se(r == NULL);
+
+        m = hashmap_new(&string_hash_ops);
+        assert_se(m);
+
+        r = hashmap_remove2(m, "no such key", &r2);
+        assert_se(r == NULL);
+
+        hashmap_put(m, strdup(key1), strdup(val1));
+        hashmap_put(m, strdup(key2), strdup(val2));
+
+        r = hashmap_remove2(m, key1, &r2);
+        assert_se(streq(r, val1));
+        assert_se(streq(r2, key1));
+        free(r);
+        free(r2);
+
+        r = hashmap_get(m, key2);
+        assert_se(streq(r, val2));
+        assert_se(!hashmap_get(m, key1));
+}
+
+static void test_hashmap_remove_value(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+        char *r;
+
+        r = hashmap_remove_value(NULL, "key 1", (void*) "val 1");
+        assert_se(r == NULL);
+
+        m = hashmap_new(&string_hash_ops);
+        assert_se(m);
+
+        r = hashmap_remove_value(m, "key 1", (void*) "val 1");
+        assert_se(r == NULL);
+
+        hashmap_put(m, "key 1", (void*) "val 1");
+        hashmap_put(m, "key 2", (void*) "val 2");
+
+        r = hashmap_remove_value(m, "key 1", (void*) "val 1");
+        assert_se(streq(r, "val 1"));
+
+        r = hashmap_get(m, "key 2");
+        assert_se(streq(r, "val 2"));
+        assert_se(!hashmap_get(m, "key 1"));
+
+        r = hashmap_remove_value(m, "key 2", (void*) "val 1");
+        assert_se(r == NULL);
+
+        r = hashmap_get(m, "key 2");
+        assert_se(streq(r, "val 2"));
+        assert_se(!hashmap_get(m, "key 1"));
+}
+
+static void test_hashmap_remove_and_put(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+        int valid;
+        char *r;
+
+        m = hashmap_new(&string_hash_ops);
+        assert_se(m);
+
+        valid = hashmap_remove_and_put(m, "invalid key", "new key", NULL);
+        assert_se(valid == -ENOENT);
+
+        valid = hashmap_put(m, "key 1", (void*) (const char *) "val 1");
+        assert_se(valid == 1);
+
+        valid = hashmap_remove_and_put(NULL, "key 1", "key 2", (void*) (const char *) "val 2");
+        assert_se(valid == -ENOENT);
+
+        valid = hashmap_remove_and_put(m, "key 1", "key 2", (void*) (const char *) "val 2");
+        assert_se(valid == 0);
+
+        r = hashmap_get(m, "key 2");
+        assert_se(streq(r, "val 2"));
+        assert_se(!hashmap_get(m, "key 1"));
+
+        valid = hashmap_put(m, "key 3", (void*) (const char *) "val 3");
+        assert_se(valid == 1);
+        valid = hashmap_remove_and_put(m, "key 3", "key 2", (void*) (const char *) "val 2");
+        assert_se(valid == -EEXIST);
+}
+
+static void test_hashmap_remove_and_replace(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+        int valid;
+        void *key1 = UINT_TO_PTR(1);
+        void *key2 = UINT_TO_PTR(2);
+        void *key3 = UINT_TO_PTR(3);
+        void *r;
+
+        m = hashmap_new(&trivial_hash_ops);
+        assert_se(m);
+
+        valid = hashmap_remove_and_replace(m, key1, key2, NULL);
+        assert_se(valid == -ENOENT);
+
+        valid = hashmap_put(m, key1, key1);
+        assert_se(valid == 1);
+
+        valid = hashmap_remove_and_replace(NULL, key1, key2, key2);
+        assert_se(valid == -ENOENT);
+
+        valid = hashmap_remove_and_replace(m, key1, key2, key2);
+        assert_se(valid == 0);
+
+        r = hashmap_get(m, key2);
+        assert_se(r == key2);
+        assert_se(!hashmap_get(m, key1));
+
+        valid = hashmap_put(m, key3, key3);
+        assert_se(valid == 1);
+        valid = hashmap_remove_and_replace(m, key3, key2, key2);
+        assert_se(valid == 0);
+        r = hashmap_get(m, key2);
+        assert_se(r == key2);
+        assert_se(!hashmap_get(m, key3));
+}
+
+static void test_hashmap_ensure_allocated(void) {
+        Hashmap *m;
+        int valid_hashmap;
+
+        m = hashmap_new(&string_hash_ops);
+
+        valid_hashmap = hashmap_ensure_allocated(&m, &string_hash_ops);
+        assert_se(valid_hashmap == 0);
+
+        assert_se(m);
+        hashmap_free(m);
+}
+
+static void test_hashmap_foreach_key(void) {
+        Hashmap *m;
+        Iterator i;
+        bool key_found[] = { false, false, false, false };
+        const char *s;
+        const char *key;
+        static const char key_table[] =
+                "key 1\0"
+                "key 2\0"
+                "key 3\0"
+                "key 4\0";
+
+        m = hashmap_new(&string_hash_ops);
+
+        NULSTR_FOREACH(key, key_table)
+                hashmap_put(m, key, (void*) (const char*) "my dummy val");
+
+        HASHMAP_FOREACH_KEY(s, key, m, i) {
+                if (!key_found[0] && streq(key, "key 1"))
+                        key_found[0] = true;
+                else if (!key_found[1] && streq(key, "key 2"))
+                        key_found[1] = true;
+                else if (!key_found[2] && streq(key, "key 3"))
+                        key_found[2] = true;
+                else if (!key_found[3] && streq(key, "fail"))
+                        key_found[3] = true;
+        }
+
+        assert_se(m);
+        assert_se(key_found[0] && key_found[1] && key_found[2] && !key_found[3]);
+
+        hashmap_free(m);
+}
+
+static void test_hashmap_foreach(void) {
+        Hashmap *m;
+        Iterator i;
+        bool value_found[] = { false, false, false, false };
+        char *val1, *val2, *val3, *val4, *s;
+        unsigned count;
+
+        val1 = strdup("my val1");
+        assert_se(val1);
+        val2 = strdup("my val2");
+        assert_se(val2);
+        val3 = strdup("my val3");
+        assert_se(val3);
+        val4 = strdup("my val4");
+        assert_se(val4);
+
+        m = NULL;
+
+        count = 0;
+        HASHMAP_FOREACH(s, m, i)
+                count++;
+        assert_se(count == 0);
+
+        m = hashmap_new(&string_hash_ops);
+
+        count = 0;
+        HASHMAP_FOREACH(s, m, i)
+                count++;
+        assert_se(count == 0);
+
+        hashmap_put(m, "Key 1", val1);
+        hashmap_put(m, "Key 2", val2);
+        hashmap_put(m, "Key 3", val3);
+        hashmap_put(m, "Key 4", val4);
+
+        HASHMAP_FOREACH(s, m, i) {
+                if (!value_found[0] && streq(s, val1))
+                        value_found[0] = true;
+                else if (!value_found[1] && streq(s, val2))
+                        value_found[1] = true;
+                else if (!value_found[2] && streq(s, val3))
+                        value_found[2] = true;
+                else if (!value_found[3] && streq(s, val4))
+                        value_found[3] = true;
+        }
+
+        assert_se(m);
+        assert_se(value_found[0] && value_found[1] && value_found[2] && value_found[3]);
+
+        hashmap_free_free(m);
+}
+
+static void test_hashmap_merge(void) {
+        Hashmap *m;
+        Hashmap *n;
+        char *val1, *val2, *val3, *val4, *r;
+
+        val1 = strdup("my val1");
+        assert_se(val1);
+        val2 = strdup("my val2");
+        assert_se(val2);
+        val3 = strdup("my val3");
+        assert_se(val3);
+        val4 = strdup("my val4");
+        assert_se(val4);
+
+        n = hashmap_new(&string_hash_ops);
+        m = hashmap_new(&string_hash_ops);
+
+        hashmap_put(m, "Key 1", val1);
+        hashmap_put(m, "Key 2", val2);
+        hashmap_put(n, "Key 3", val3);
+        hashmap_put(n, "Key 4", val4);
+
+        assert_se(hashmap_merge(m, n) == 0);
+        r = hashmap_get(m, "Key 3");
+        assert_se(r && streq(r, "my val3"));
+        r = hashmap_get(m, "Key 4");
+        assert_se(r && streq(r, "my val4"));
+
+        assert_se(n);
+        assert_se(m);
+        hashmap_free(n);
+        hashmap_free_free(m);
+}
+
+static void test_hashmap_contains(void) {
+        Hashmap *m;
+        char *val1;
+
+        val1 = strdup("my val");
+        assert_se(val1);
+
+        m = hashmap_new(&string_hash_ops);
+
+        assert_se(!hashmap_contains(m, "Key 1"));
+        hashmap_put(m, "Key 1", val1);
+        assert_se(hashmap_contains(m, "Key 1"));
+        assert_se(!hashmap_contains(m, "Key 2"));
+
+        assert_se(!hashmap_contains(NULL, "Key 1"));
+
+        assert_se(m);
+        hashmap_free_free(m);
+}
+
+static void test_hashmap_isempty(void) {
+        Hashmap *m;
+        char *val1;
+
+        val1 = strdup("my val");
+        assert_se(val1);
+
+        m = hashmap_new(&string_hash_ops);
+
+        assert_se(hashmap_isempty(m));
+        hashmap_put(m, "Key 1", val1);
+        assert_se(!hashmap_isempty(m));
+
+        assert_se(m);
+        hashmap_free_free(m);
+}
+
+static void test_hashmap_size(void) {
+        Hashmap *m;
+        char *val1, *val2, *val3, *val4;
+
+        val1 = strdup("my val");
+        assert_se(val1);
+        val2 = strdup("my val");
+        assert_se(val2);
+        val3 = strdup("my val");
+        assert_se(val3);
+        val4 = strdup("my val");
+        assert_se(val4);
+
+        assert_se(hashmap_size(NULL) == 0);
+        assert_se(hashmap_buckets(NULL) == 0);
+
+        m = hashmap_new(&string_hash_ops);
+
+        hashmap_put(m, "Key 1", val1);
+        hashmap_put(m, "Key 2", val2);
+        hashmap_put(m, "Key 3", val3);
+        hashmap_put(m, "Key 4", val4);
+
+        assert_se(m);
+        assert_se(hashmap_size(m) == 4);
+        assert_se(hashmap_buckets(m) >= 4);
+        hashmap_free_free(m);
+}
+
+static void test_hashmap_get(void) {
+        Hashmap *m;
+        char *r;
+        char *val;
+
+        val = strdup("my val");
+        assert_se(val);
+
+        r = hashmap_get(NULL, "Key 1");
+        assert_se(r == NULL);
+
+        m = hashmap_new(&string_hash_ops);
+
+        hashmap_put(m, "Key 1", val);
+
+        r = hashmap_get(m, "Key 1");
+        assert_se(streq(r, val));
+
+        r = hashmap_get(m, "no such key");
+        assert_se(r == NULL);
+
+        assert_se(m);
+        hashmap_free_free(m);
+}
+
+static void test_hashmap_get2(void) {
+        Hashmap *m;
+        char *r;
+        char *val;
+        char key_orig[] = "Key 1";
+        void *key_copy;
+
+        val = strdup("my val");
+        assert_se(val);
+
+        key_copy = strdup(key_orig);
+        assert_se(key_copy);
+
+        r = hashmap_get2(NULL, key_orig, &key_copy);
+        assert_se(r == NULL);
+
+        m = hashmap_new(&string_hash_ops);
+
+        hashmap_put(m, key_copy, val);
+        key_copy = NULL;
+
+        r = hashmap_get2(m, key_orig, &key_copy);
+        assert_se(streq(r, val));
+        assert_se(key_orig != key_copy);
+        assert_se(streq(key_orig, key_orig));
+
+        r = hashmap_get2(m, "no such key", NULL);
+        assert_se(r == NULL);
+
+        assert_se(m);
+        hashmap_free_free_free(m);
+}
+
+static unsigned long crippled_hashmap_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
+        return trivial_hash_func(p, hash_key) & 0xff;
+}
+
+static const struct hash_ops crippled_hashmap_ops = {
+        .hash = crippled_hashmap_func,
+        .compare = trivial_compare_func,
+};
+
+static void test_hashmap_many(void) {
+        Hashmap *h;
+        unsigned i, j;
+        void *v, *k;
+        static const struct {
+                const struct hash_ops *ops;
+                unsigned n_entries;
+        } tests[] = {
+                { .ops = NULL,                  .n_entries = 1 << 20 },
+                { .ops = &crippled_hashmap_ops, .n_entries = 1 << 11 },
+        };
+
+
+        for (j = 0; j < ELEMENTSOF(tests); j++) {
+                assert_se(h = hashmap_new(tests[j].ops));
+
+                for (i = 1; i < tests[j].n_entries*3; i+=3) {
+                        assert_se(hashmap_put(h, UINT_TO_PTR(i), UINT_TO_PTR(i)) >= 0);
+                        assert_se(PTR_TO_UINT(hashmap_get(h, UINT_TO_PTR(i))) == i);
+                }
+
+                for (i = 1; i < tests[j].n_entries*3; i++)
+                        assert_se(hashmap_contains(h, UINT_TO_PTR(i)) == (i % 3 == 1));
+
+                log_info("%u <= %u * 0.75 = %g", hashmap_size(h), hashmap_buckets(h), hashmap_buckets(h) * 0.75);
+
+                assert_se(hashmap_size(h) <= hashmap_buckets(h) * 0.75);
+                assert_se(hashmap_size(h) == tests[j].n_entries);
+
+                while (!hashmap_isempty(h)) {
+                        k = hashmap_first_key(h);
+                        v = hashmap_remove(h, k);
+                        assert_se(v == k);
+                }
+
+                hashmap_free(h);
+        }
+}
+
+static void test_hashmap_first(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+
+        m = hashmap_new(&string_hash_ops);
+        assert_se(m);
+
+        assert_se(!hashmap_first(m));
+        assert_se(hashmap_put(m, "key 1", (void*) "val 1") == 1);
+        assert_se(streq(hashmap_first(m), "val 1"));
+        assert_se(hashmap_put(m, "key 2", (void*) "val 2") == 1);
+#ifdef ORDERED
+        assert_se(streq(hashmap_first(m), "val 1"));
+        assert_se(hashmap_remove(m, "key 1"));
+        assert_se(streq(hashmap_first(m), "val 2"));
+#endif
+}
+
+static void test_hashmap_first_key(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+
+        m = hashmap_new(&string_hash_ops);
+        assert_se(m);
+
+        assert_se(!hashmap_first_key(m));
+        assert_se(hashmap_put(m, "key 1", NULL) == 1);
+        assert_se(streq(hashmap_first_key(m), "key 1"));
+        assert_se(hashmap_put(m, "key 2", NULL) == 1);
+#ifdef ORDERED
+        assert_se(streq(hashmap_first_key(m), "key 1"));
+        assert_se(hashmap_remove(m, "key 1") == NULL);
+        assert_se(streq(hashmap_first_key(m), "key 2"));
+#endif
+}
+
+static void test_hashmap_steal_first_key(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+
+        m = hashmap_new(&string_hash_ops);
+        assert_se(m);
+
+        assert_se(!hashmap_steal_first_key(m));
+        assert_se(hashmap_put(m, "key 1", NULL) == 1);
+        assert_se(streq(hashmap_steal_first_key(m), "key 1"));
+
+        assert_se(hashmap_isempty(m));
+}
+
+static void test_hashmap_steal_first(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+        int seen[3] = {};
+        char *val;
+
+        m = hashmap_new(&string_hash_ops);
+        assert_se(m);
+
+        assert_se(hashmap_put(m, "key 1", (void*) "1") == 1);
+        assert_se(hashmap_put(m, "key 2", (void*) "22") == 1);
+        assert_se(hashmap_put(m, "key 3", (void*) "333") == 1);
+
+        while ((val = hashmap_steal_first(m)))
+                seen[strlen(val) - 1]++;
+
+        assert_se(seen[0] == 1 && seen[1] == 1 && seen[2] == 1);
+
+        assert_se(hashmap_isempty(m));
+}
+
+static void test_hashmap_clear_free_free(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+
+        m = hashmap_new(&string_hash_ops);
+        assert_se(m);
+
+        assert_se(hashmap_put(m, strdup("key 1"), NULL) == 1);
+        assert_se(hashmap_put(m, strdup("key 2"), NULL) == 1);
+        assert_se(hashmap_put(m, strdup("key 3"), NULL) == 1);
+
+        hashmap_clear_free_free(m);
+        assert_se(hashmap_isempty(m));
+}
+
+static void test_hashmap_reserve(void) {
+        _cleanup_hashmap_free_ Hashmap *m = NULL;
+
+        m = hashmap_new(&string_hash_ops);
+
+        assert_se(hashmap_reserve(m, 1) == 0);
+        assert_se(hashmap_buckets(m) < 1000);
+        assert_se(hashmap_reserve(m, 1000) == 0);
+        assert_se(hashmap_buckets(m) >= 1000);
+        assert_se(hashmap_isempty(m));
+
+        assert_se(hashmap_put(m, "key 1", (void*) "val 1") == 1);
+
+        assert_se(hashmap_reserve(m, UINT_MAX) == -ENOMEM);
+        assert_se(hashmap_reserve(m, UINT_MAX - 1) == -ENOMEM);
+}
+
+void test_hashmap_funcs(void) {
+        test_hashmap_copy();
+        test_hashmap_get_strv();
+        test_hashmap_move_one();
+        test_hashmap_move();
+        test_hashmap_replace();
+        test_hashmap_update();
+        test_hashmap_put();
+        test_hashmap_remove();
+        test_hashmap_remove2();
+        test_hashmap_remove_value();
+        test_hashmap_remove_and_put();
+        test_hashmap_remove_and_replace();
+        test_hashmap_ensure_allocated();
+        test_hashmap_foreach();
+        test_hashmap_foreach_key();
+        test_hashmap_contains();
+        test_hashmap_merge();
+        test_hashmap_isempty();
+        test_hashmap_get();
+        test_hashmap_get2();
+        test_hashmap_size();
+        test_hashmap_many();
+        test_hashmap_first();
+        test_hashmap_first_key();
+        test_hashmap_steal_first_key();
+        test_hashmap_steal_first();
+        test_hashmap_clear_free_free();
+        test_hashmap_reserve();
+}
diff -urN systemd-216/src/test/test-sched-prio.c systemd-217/src/test/test-sched-prio.c
--- systemd-216/src/test/test-sched-prio.c	2014-11-03 09:35:35.119249007 -0800
+++ systemd-217/src/test/test-sched-prio.c	2014-10-13 08:19:31.026675574 -0700
@@ -35,7 +35,7 @@
         /* prepare the test */
         assert_se(set_unit_path(TEST_DIR) >= 0);
         r = manager_new(SYSTEMD_USER, true, &m);
-        if (r == -EPERM || r == -EACCES || r == -EADDRINUSE || r == -EHOSTDOWN) {
+        if (IN_SET(r, -EPERM, -EACCES, -EADDRINUSE, -EHOSTDOWN, -ENOENT)) {
                 printf("Skipping test: manager_new: %s", strerror(-r));
                 return EXIT_TEST_SKIP;
         }
diff -urN systemd-216/src/test/test-udev.c systemd-217/src/test/test-udev.c
--- systemd-216/src/test/test-udev.c	2014-11-03 09:35:28.376181017 -0800
+++ systemd-217/src/test/test-udev.c	2014-10-23 08:13:15.781717938 -0700
@@ -99,7 +99,7 @@
                 return EXIT_FAILURE;
 
         log_debug("version %s", VERSION);
-        label_init("/dev");
+        mac_selinux_init("/dev");
 
         sigprocmask(SIG_SETMASK, NULL, &sigmask_orig);
 
@@ -158,7 +158,7 @@
 out:
         if (event != NULL && event->fd_signal >= 0)
                 close(event->fd_signal);
-        label_finish();
+        mac_selinux_finish();
 
         return err ? EXIT_FAILURE : EXIT_SUCCESS;
 }
diff -urN systemd-216/src/timedate/timedated.c systemd-217/src/timedate/timedated.c
--- systemd-216/src/timedate/timedated.c	2014-11-03 09:35:37.342271422 -0800
+++ systemd-217/src/timedate/timedated.c	2014-11-03 09:33:48.312172072 -0800
@@ -176,7 +176,7 @@
                 }
         }
 
-        label_init("/etc");
+        mac_selinux_init("/etc");
         return write_string_file_atomic_label("/etc/adjtime", w);
 }
 
diff -urN systemd-216/src/timesync/timesyncd-manager.c systemd-217/src/timesync/timesyncd-manager.c
--- systemd-216/src/timesync/timesyncd-manager.c	2014-11-03 09:35:29.805195426 -0800
+++ systemd-217/src/timesync/timesyncd-manager.c	2014-10-24 09:31:52.799566165 -0700
@@ -54,8 +54,7 @@
 #include "mkdir.h"
 #include "timesyncd-conf.h"
 #include "timesyncd-manager.h"
-
-#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
+#include "time-util.h"
 
 #ifndef ADJ_SETOFFSET
 #define ADJ_SETOFFSET                   0x0100  /* add 'time' to current time */
@@ -721,9 +720,7 @@
         if (r < 0)
                 return -errno;
 
-        r = setsockopt(m->server_socket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
-        if (r < 0)
-                return -errno;
+        (void) setsockopt(m->server_socket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
 
         return sd_event_add_io(m->event, &m->event_receive, m->server_socket, EPOLLIN, manager_receive_response, m);
 }
diff -urN systemd-216/src/tmpfiles/tmpfiles.c systemd-217/src/tmpfiles/tmpfiles.c
--- systemd-216/src/tmpfiles/tmpfiles.c	2014-11-03 09:35:33.029227934 -0800
+++ systemd-217/src/tmpfiles/tmpfiles.c	2014-10-23 12:36:56.810756232 -0700
@@ -259,7 +259,7 @@
 
         /* got only one handle; assume different mount points if one
          * of both queries was not supported by the filesystem */
-        if (r_p == -ENOSYS || r_p == -ENOTSUP || r == -ENOSYS || r == -ENOTSUP)
+        if (r_p == -ENOSYS || r_p == -EOPNOTSUPP || r == -ENOSYS || r == -EOPNOTSUPP)
                 return true;
 
         /* return error */
@@ -509,9 +509,9 @@
                 i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC|O_NOFOLLOW : 0;
 
         RUN_WITH_UMASK(0000) {
-                label_context_set(path, S_IFREG);
+                mac_selinux_create_file_prepare(path, S_IFREG);
                 fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY, i->mode);
-                label_context_clear();
+                mac_selinux_create_file_clear();
         }
 
         if (fd < 0) {
@@ -743,9 +743,9 @@
         case CREATE_FIFO:
 
                 RUN_WITH_UMASK(0000) {
-                        label_context_set(i->path, S_IFIFO);
+                        mac_selinux_create_file_prepare(i->path, S_IFIFO);
                         r = mkfifo(i->path, i->mode);
-                        label_context_clear();
+                        mac_selinux_create_file_clear();
                 }
 
                 if (r < 0) {
@@ -764,9 +764,9 @@
                                 if (i->force) {
 
                                         RUN_WITH_UMASK(0000) {
-                                                label_context_set(i->path, S_IFIFO);
+                                                mac_selinux_create_file_prepare(i->path, S_IFIFO);
                                                 r = mkfifo_atomic(i->path, i->mode);
-                                                label_context_clear();
+                                                mac_selinux_create_file_clear();
                                         }
 
                                         if (r < 0) {
@@ -788,9 +788,9 @@
 
         case CREATE_SYMLINK:
 
-                label_context_set(i->path, S_IFLNK);
+                mac_selinux_create_file_prepare(i->path, S_IFLNK);
                 r = symlink(i->argument, i->path);
-                label_context_clear();
+                mac_selinux_create_file_clear();
 
                 if (r < 0) {
                         _cleanup_free_ char *x = NULL;
@@ -804,9 +804,9 @@
                         if (r < 0 || !streq(i->argument, x)) {
 
                                 if (i->force) {
-                                        label_context_set(i->path, S_IFLNK);
+                                        mac_selinux_create_file_prepare(i->path, S_IFLNK);
                                         r = symlink_atomic(i->argument, i->path);
-                                        label_context_clear();
+                                        mac_selinux_create_file_clear();
 
                                         if (r < 0) {
                                                 log_error("symlink(%s, %s) failed: %s", i->argument, i->path, strerror(-r));
@@ -838,9 +838,9 @@
                 file_type = i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR;
 
                 RUN_WITH_UMASK(0000) {
-                        label_context_set(i->path, file_type);
+                        mac_selinux_create_file_prepare(i->path, file_type);
                         r = mknod(i->path, i->mode | file_type, i->major_minor);
-                        label_context_clear();
+                        mac_selinux_create_file_clear();
                 }
 
                 if (r < 0) {
@@ -865,9 +865,9 @@
                                 if (i->force) {
 
                                         RUN_WITH_UMASK(0000) {
-                                                label_context_set(i->path, file_type);
+                                                mac_selinux_create_file_prepare(i->path, file_type);
                                                 r = mknod_atomic(i->path, i->mode | file_type, i->major_minor);
-                                                label_context_clear();
+                                                mac_selinux_create_file_clear();
                                         }
 
                                         if (r < 0) {
@@ -1610,7 +1610,7 @@
 
         umask(0022);
 
-        label_init(NULL);
+        mac_selinux_init(NULL);
 
         items = hashmap_new(&string_hash_ops);
         globs = hashmap_new(&string_hash_ops);
@@ -1670,7 +1670,7 @@
 
         set_free_free(unix_sockets);
 
-        label_finish();
+        mac_selinux_finish();
 
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
diff -urN systemd-216/src/udev/cdrom_id/cdrom_id.c systemd-217/src/udev/cdrom_id/cdrom_id.c
--- systemd-216/src/udev/cdrom_id/cdrom_id.c	2014-08-11 10:56:20.745269015 -0700
+++ systemd-217/src/udev/cdrom_id/cdrom_id.c	2014-10-28 04:23:14.064133828 -0700
@@ -606,7 +606,7 @@
                 switch (feature) {
                 case 0x00:
                         log_debug("GET CONFIGURATION: feature 'profiles', with %i entries", features[i+3] / 4);
-                        feature_profiles(udev, &features[i]+4, features[i+3]);
+                        feature_profiles(udev, &features[i]+4, MIN(features[i+3], len - i - 4));
                         break;
                 default:
                         log_debug("GET CONFIGURATION: feature 0x%04x <ignored>, with 0x%02x bytes", feature, features[i+3]);
diff -urN systemd-216/src/udev/scsi_id/scsi_id.c systemd-217/src/udev/scsi_id/scsi_id.c
--- systemd-216/src/udev/scsi_id/scsi_id.c	2014-08-11 10:56:20.712269030 -0700
+++ systemd-217/src/udev/scsi_id/scsi_id.c	2014-11-03 09:33:49.172180743 -0800
@@ -317,8 +317,8 @@
                "  -f,--config=                     location of config file\n"
                "  -p,--page=0x80|0x83|pre-spc3-83  SCSI page (0x80, 0x83, pre-spc3-83)\n"
                "  -s,--sg-version=3|4              use SGv3 or SGv4\n"
-               "  -b,--blacklisted                 threat device as blacklisted\n"
-               "  -g,--whitelisted                 threat device as whitelisted\n"
+               "  -b,--blacklisted                 treat device as blacklisted\n"
+               "  -g,--whitelisted                 treat device as whitelisted\n"
                "  -u,--replace-whitespace          replace all whitespace by underscores\n"
                "  -v,--verbose                     verbose logging\n"
                "     --version                     print version\n"
diff -urN systemd-216/src/udev/udevadm.c systemd-217/src/udev/udevadm.c
--- systemd-216/src/udev/udevadm.c	2014-11-03 09:35:23.119128010 -0800
+++ systemd-217/src/udev/udevadm.c	2014-10-23 08:13:15.783717947 -0700
@@ -99,7 +99,7 @@
         log_parse_environment();
         log_open();
         udev_set_log_fn(udev, udev_main_log);
-        label_init("/dev");
+        mac_selinux_init("/dev");
 
         while ((c = getopt_long(argc, argv, "+dhV", options, NULL)) >= 0)
                 switch (c) {
@@ -137,7 +137,7 @@
         fprintf(stderr, "%s: missing or unknown command\n", program_invocation_short_name);
         rc = 2;
 out:
-        label_finish();
+        mac_selinux_finish();
         udev_unref(udev);
         log_close();
         return rc;
diff -urN systemd-216/src/udev/udevadm-hwdb.c systemd-217/src/udev/udevadm-hwdb.c
--- systemd-216/src/udev/udevadm-hwdb.c	2014-11-03 09:35:29.667194034 -0800
+++ systemd-217/src/udev/udevadm-hwdb.c	2014-10-28 06:31:25.105131602 -0700
@@ -536,14 +536,20 @@
 static void help(void) {
         printf("Usage: udevadm hwdb OPTIONS\n"
                "  -u,--update          update the hardware database\n"
+               "  --usr                generate in " UDEVLIBEXECDIR " instead of /etc/udev\n"
                "  -t,--test=MODALIAS   query database and print result\n"
                "  -r,--root=PATH       alternative root path in the filesystem\n"
                "  -h,--help\n\n");
 }
 
 static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
+        enum {
+                ARG_USR = 0x100,
+        };
+
         static const struct option options[] = {
                 { "update", no_argument,       NULL, 'u' },
+                { "usr",    no_argument,       NULL, ARG_USR },
                 { "test",   required_argument, NULL, 't' },
                 { "root",   required_argument, NULL, 'r' },
                 { "help",   no_argument,       NULL, 'h' },
@@ -551,6 +557,7 @@
         };
         const char *test = NULL;
         const char *root = "";
+        const char *hwdb_bin_dir = "/etc/udev";
         bool update = false;
         struct trie *trie = NULL;
         int err, c;
@@ -561,6 +568,9 @@
                 case 'u':
                         update = true;
                         break;
+                case ARG_USR:
+                        hwdb_bin_dir = UDEVLIBEXECDIR;
+                        break;
                 case 't':
                         test = optarg;
                         break;
@@ -634,7 +644,8 @@
                 log_debug("strings dedup'ed: %8zu bytes (%8zu)",
                           trie->strings->dedup_len, trie->strings->dedup_count);
 
-                if (asprintf(&hwdb_bin, "%s/etc/udev/hwdb.bin", root) < 0) {
+                hwdb_bin = strjoin(root, "/", hwdb_bin_dir, "/hwdb.bin", NULL);
+                if (!hwdb_bin) {
                         rc = EXIT_FAILURE;
                         goto out;
                 }
diff -urN systemd-216/src/udev/udev-builtin-path_id.c systemd-217/src/udev/udev-builtin-path_id.c
--- systemd-216/src/udev/udev-builtin-path_id.c	2014-08-04 09:58:23.609783740 -0700
+++ systemd-217/src/udev/udev-builtin-path_id.c	2014-11-03 09:33:48.620175178 -0800
@@ -332,7 +332,7 @@
         return parent;
 }
 
-static struct udev_device *handle_scsi(struct udev_device *parent, char **path) {
+static struct udev_device *handle_scsi(struct udev_device *parent, char **path, bool *supported_parent) {
         const char *devtype;
         const char *name;
         const char *id;
@@ -346,6 +346,7 @@
         if (id != NULL) {
                 parent = skip_subsystem(parent, "scsi");
                 path_prepend(path, "ieee1394-0x%s", id);
+                *supported_parent = true;
                 goto out;
         }
 
@@ -354,16 +355,19 @@
 
         if (strstr(name, "/rport-") != NULL) {
                 parent = handle_scsi_fibre_channel(parent, path);
+                *supported_parent = true;
                 goto out;
         }
 
         if (strstr(name, "/end_device-") != NULL) {
                 parent = handle_scsi_sas(parent, path);
+                *supported_parent = true;
                 goto out;
         }
 
         if (strstr(name, "/session") != NULL) {
                 parent = handle_scsi_iscsi(parent, path);
+                *supported_parent = true;
                 goto out;
         }
 
@@ -502,7 +506,7 @@
                 } else if (streq(subsys, "scsi_tape")) {
                         handle_scsi_tape(parent, &path);
                 } else if (streq(subsys, "scsi")) {
-                        parent = handle_scsi(parent, &path);
+                        parent = handle_scsi(parent, &path, &supported_parent);
                         supported_transport = true;
                 } else if (streq(subsys, "cciss")) {
                         parent = handle_cciss(parent, &path);
@@ -544,9 +548,9 @@
         }
 
         /*
-         * Do return devices with have an unknown type of parent device, they
-         * might produce conflicting IDs below multiple independent parent
-         * devices.
+         * Do not return devices with an unknown parent device type. They
+         * might produce conflicting IDs if the parent does not provide a
+         * unique and predictable name.
          */
         if (!supported_parent) {
                 free(path);
@@ -554,9 +558,9 @@
         }
 
         /*
-         * Do not return a have-only a single-parent block devices, some
-         * have entire hidden buses behind it, and not create predictable
-         * IDs that way.
+         * Do not return block devices without a well-known transport. Some
+         * devices do not expose their buses and do not provide a unique
+         * and predictable name that way.
          */
         if (streq(udev_device_get_subsystem(dev), "block") && !supported_transport) {
                 free(path);
diff -urN systemd-216/src/udev/udevd.c systemd-217/src/udev/udevd.c
--- systemd-216/src/udev/udevd.c	2014-11-03 09:35:29.778195153 -0800
+++ systemd-217/src/udev/udevd.c	2014-10-23 08:13:15.784717951 -0700
@@ -1139,7 +1139,7 @@
                 goto exit;
         }
 
-        r = label_init("/dev");
+        r = mac_selinux_init("/dev");
         if (r < 0) {
                 log_error("could not initialize labelling: %s", strerror(-r));
                 goto exit;
@@ -1542,7 +1542,7 @@
         udev_monitor_unref(monitor);
         udev_ctrl_connection_unref(ctrl_conn);
         udev_ctrl_unref(udev_ctrl);
-        label_finish();
+        mac_selinux_finish();
         udev_unref(udev);
         log_close();
         return rc;
diff -urN systemd-216/src/udev/udev-node.c systemd-217/src/udev/udev-node.c
--- systemd-216/src/udev/udev-node.c	2014-11-03 09:35:29.696194327 -0800
+++ systemd-217/src/udev/udev-node.c	2014-10-24 04:56:24.044133834 -0700
@@ -88,11 +88,11 @@
                         err = mkdir_parents_label(slink, 0755);
                         if (err != 0 && err != -ENOENT)
                                 break;
-                        label_context_set(slink, S_IFLNK);
+                        mac_selinux_create_file_prepare(slink, S_IFLNK);
                         err = symlink(target, slink);
                         if (err != 0)
                                 err = -errno;
-                        label_context_clear();
+                        mac_selinux_create_file_clear();
                 } while (err == -ENOENT);
                 if (err == 0)
                         goto exit;
@@ -105,11 +105,11 @@
                 err = mkdir_parents_label(slink_tmp, 0755);
                 if (err != 0 && err != -ENOENT)
                         break;
-                label_context_set(slink_tmp, S_IFLNK);
+                mac_selinux_create_file_prepare(slink_tmp, S_IFLNK);
                 err = symlink(target, slink_tmp);
                 if (err != 0)
                         err = -errno;
-                label_context_clear();
+                mac_selinux_create_file_clear();
         } while (err == -ENOENT);
         if (err != 0) {
                 log_error("symlink '%s' '%s' failed: %m", target, slink_tmp);
@@ -294,21 +294,26 @@
                 /* apply SECLABEL{$module}=$label */
                 udev_list_entry_foreach(entry, udev_list_get_entry(seclabel_list)) {
                         const char *name, *label;
+                        int r;
 
                         name = udev_list_entry_get_name(entry);
                         label = udev_list_entry_get_value(entry);
 
                         if (streq(name, "selinux")) {
                                 selinux = true;
-                                if (label_apply(devnode, label) < 0)
-                                        log_error("SECLABEL: failed to set SELinux label '%s'", label);
+
+                                r = mac_selinux_apply(devnode, label);
+                                if (r < 0)
+                                        log_error("SECLABEL: failed to set SELinux label '%s': %s", label, strerror(-r));
                                 else
                                         log_debug("SECLABEL: set SELinux label '%s'", label);
 
                         } else if (streq(name, "smack")) {
                                 smack = true;
-                                if (smack_label_path(devnode, label) < 0)
-                                        log_error("SECLABEL: failed to set SMACK label '%s'", label);
+
+                                r = mac_smack_apply(devnode, label);
+                                if (r < 0)
+                                        log_error("SECLABEL: failed to set SMACK label '%s': %s", label, strerror(-r));
                                 else
                                         log_debug("SECLABEL: set SMACK label '%s'", label);
 
@@ -318,9 +323,9 @@
 
                 /* set the defaults */
                 if (!selinux)
-                        label_fix(devnode, true, false);
+                        mac_selinux_fix(devnode, true, false);
                 if (!smack)
-                        smack_label_path(devnode, NULL);
+                        mac_smack_apply(devnode, NULL);
         }
 
         /* always update timestamp when we re-use the node, like on media change events */
diff -urN systemd-216/src/update-done/update-done.c systemd-217/src/update-done/update-done.c
--- systemd-216/src/update-done/update-done.c	2014-07-29 10:51:00.747286124 -0700
+++ systemd-217/src/update-done/update-done.c	2014-10-23 12:36:56.810756232 -0700
@@ -61,7 +61,7 @@
 
                 /* The timestamp file doesn't exist yet? Then let's create it. */
 
-                r = label_context_set(path, S_IFREG);
+                r = mac_selinux_create_file_prepare(path, S_IFREG);
                 if (r < 0) {
                         log_error("Failed to set SELinux context for %s: %s",
                                   path, strerror(-r));
@@ -69,7 +69,7 @@
                 }
 
                 fd = open(path, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
-                label_context_clear();
+                mac_selinux_create_file_clear();
 
                 if (fd < 0) {
 
@@ -112,7 +112,7 @@
                 return EXIT_FAILURE;
         }
 
-        r = label_init(NULL);
+        r = mac_selinux_init(NULL);
         if (r < 0) {
                 log_error("SELinux setup failed: %s", strerror(-r));
                 goto finish;
diff -urN systemd-216/test/basic.target systemd-217/test/basic.target
--- systemd-216/test/basic.target	2014-06-29 13:27:07.761305646 -0700
+++ systemd-217/test/basic.target	2014-10-27 18:19:55.429947979 -0700
@@ -11,3 +11,5 @@
 Requires=sysinit.target
 Wants=sockets.target timers.target paths.target slices.target
 After=sysinit.target sockets.target timers.target paths.target slices.target
+JobTimeoutSec=15min
+JobTimeoutAction=poweroff-force
diff -urN systemd-216/test-libsystemd-sym.c systemd-217/test-libsystemd-sym.c
--- systemd-216/test-libsystemd-sym.c	2014-08-19 14:26:12.615884172 -0700
+++ systemd-217/test-libsystemd-sym.c	2014-10-28 09:32:32.548489354 -0700
@@ -124,6 +124,7 @@
 sd_pid_notify,
 sd_pid_notifyf,
 sd_machine_get_ifindices,
+sd_session_get_desktop,
 sd_bus_default,
 sd_bus_default_user,
 sd_bus_default_system,
@@ -153,7 +154,7 @@
 sd_bus_is_open,
 sd_bus_can_send,
 sd_bus_get_server_id,
-sd_bus_get_peer_creds,
+sd_bus_get_owner_creds,
 sd_bus_get_name,
 sd_bus_send,
 sd_bus_send_to,
@@ -249,8 +250,8 @@
 sd_bus_request_name,
 sd_bus_release_name,
 sd_bus_list_names,
-sd_bus_get_owner,
-sd_bus_get_owner_machine_id,
+sd_bus_get_name_creds,
+sd_bus_get_name_machine_id,
 sd_bus_call_method,
 sd_bus_get_property,
 sd_bus_get_property_trivial,
@@ -339,6 +340,7 @@
 sd_event_loop,
 sd_event_exit,
 sd_event_now,
+sd_event_get_fd,
 sd_event_get_state,
 sd_event_get_tid,
 sd_event_get_exit_code,
@@ -346,6 +348,8 @@
 sd_event_get_watchdog,
 sd_event_source_ref,
 sd_event_source_unref,
+sd_event_source_set_name,
+sd_event_source_get_name,
 sd_event_source_set_prepare,
 sd_event_source_get_pending,
 sd_event_source_get_priority,
diff -urN systemd-216/test-libudev-sym.c systemd-217/test-libudev-sym.c
--- systemd-216/test-libudev-sym.c	2014-08-19 14:26:12.617884172 -0700
+++ systemd-217/test-libudev-sym.c	2014-10-28 09:32:32.546489320 -0700
@@ -74,8 +74,6 @@
 udev_queue_get_udev,
 udev_queue_get_udev_is_active,
 udev_queue_get_udev_seqnum,
-udev_queue_get_fd,
-udev_queue_flush,
 udev_queue_new,
 udev_queue_ref,
 udev_queue_unref,
@@ -91,6 +89,8 @@
 udev_hwdb_unref,
 udev_hwdb_get_properties_list_entry,
 udev_device_set_sysattr_value,
+udev_queue_flush,
+udev_queue_get_fd,
 };
 int main(void) {
 unsigned i; for (i=0;i<sizeof(functions)/sizeof(void*);i++) printf("%p\n", functions[i]);
diff -urN systemd-216/tmpfiles.d/.gitignore systemd-217/tmpfiles.d/.gitignore
--- systemd-216/tmpfiles.d/.gitignore	2014-11-03 09:35:23.001126820 -0800
+++ systemd-217/tmpfiles.d/.gitignore	1969-12-31 16:00:00.000000000 -0800
@@ -1 +0,0 @@
-etc.conf
diff -urN systemd-216/TODO systemd-217/TODO
--- systemd-216/TODO	2014-11-03 09:35:36.949267459 -0800
+++ systemd-217/TODO	2014-11-03 09:33:48.496173927 -0800
@@ -1,6 +1,8 @@
+Fixes needed before 217:
+
+* verify that both resolved and timesyncd work OK without networkd around
+
 Bugfixes:
-* Re-enable "fsck -l" when it is ready:
-   https://bugs.freedesktop.org/show_bug.cgi?id=79576#c5
 
 * Should systemctl status \* work on all unit types, not just .service?
 
@@ -10,19 +12,15 @@
 
 * properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point.
 
-After killing 'systemd --user', systemctl restart user@... fails.
-/run/user/1000/systemd/notify has to be removed manually.
-
-ExecStart with unicode characters fails in strv_split_quoted:
+* ExecStart with unicode characters fails in strv_split_quoted:
 
           [Service]
           Environment=ONE='one' "TWO='two two' too" THREE=
           ExecStart=/bin/python3 -c 'import sys;print(sys.argv)' $ONE $TWO $THREE
 
-MEMORY return code is overloaded for syntax errors in the commandline.
-str_split_quoted() should return a real return code, so spawn_child can
-report the failure properly.
-
+* MEMORY return code is overloaded for syntax errors in the commandline.
+  str_split_quoted() should return a real return code, so spawn_child can
+  report the failure properly.
 
 External:
 * Fedora: add an rpmlint check that verifies that all unit files in the RPM are listed in %systemd_post macros.
@@ -40,19 +38,42 @@
 
 Features:
 
+* journald: allow per-priority and per-service retention times when rotating/vacuuming
+
+* introduce systemd-timesync-wait.service or so to sync on an NTP fix?
+
+* systemd --user should issue sd_notify() upon reaching basic.target, not on becoming idle
+
+* configure.ac pretends dbus was optional but actually hardcodes use of dbus' pkg-config file to determine various dbus dirs such as policy and activation dirs
+
+* consider showing the unit names during boot up in the status output, not just the unit descriptions
+
+* send SIGABRT when a service watchdog is triggered, by default, so that we acquire a backtrace of the hang.
+
+* dhcp: do we allow configuring dhcp routes on interfaces that are not the one we got the dhcp info from?
+
+* maybe allow timer units with an empty Units= setting, so that they
+  can be used for resuming the system but nothing else.
+
+* what to do about udev db binary stability for apps?
+
+* maybe provide an API to allow migration of foreign PIDs into existing scopes.
+
+* kdbus: maybe rename "connection name" concept to something that doesn't reuse the word "name"?
+
+* PID 1 doesn't apply nspawns devices cgroup policy
+
+* rework journal-send.c to use memfds for large blobs if they are available instead of unlinked files in /tmp. Also, if we detect that the kernel knows memfds, refuse anything but sealed memfds.
+
 * maybe support a new very "soft" reboot mode, that simply kills all processes, disassembles everything, flushes /run and sysvipc, and then reexecs systemd again
 
 * man: document that corrupted journal files is nothing to act on
 
-* systemctl isolate should use ".target" as completion suffix, not ".service"
-
 * bus-proxy: when passing messages from kdbus, make sure we properly
   handle the case where a large number of fds is appended that we
   cannot pass into sendmsg() of the AF_UNIX sokcet (which only accepts
   253 messages)
 
-* check for validity of ucred fields in bus-proxy, like we do in journald
-
 * busctl: add a pcap writer, using LINKTYPE_DBUS/231
 
 * man: maybe use the word "inspect" rather than "introspect"?
@@ -67,8 +88,6 @@
 
 * maybe add "systemctl edit" that copies unit files from /usr/lib/systemd/system to /etc/systemd/system and invokes vim on them
 
-* dbus: add new message hdr field for allowing interactive auth, write spec for it. update dbus spec to mandate that unknown flags *must* be ignored...
-
 * maybe introduce AssertXYZ= similar to ConditionXYZ= that causes a unit to fail (instead of skipping it) if some condition is not true...
 
 * remove multi-seat-x now
@@ -77,10 +96,6 @@
 
 * exponential backoff in timesyncd and resolved when we cannot reach a server
 
-* apply start timeout during the "initializing" manager state only,
-  instead of both "initializing" and "starting". maybe rename the
-  timeout to "initialization-timeout" then or so?
-
 * journald: make use of uid-range.h to managed uid ranges to split
   journals in.
 
@@ -97,8 +112,6 @@
 
 * merge ~/.local/share and ~/.local/lib into one similar /usr/lib and /usr/share....
 
-* remove readahead in 217
-
 * journald: allows specification of UID range for splitting up journal files
 
 * systemd.show_status= should probably have a mode where only failed
@@ -121,6 +134,8 @@
     to clients. It should also pass on its own timezone information.
   - provide a way to define a per-network interface default metric value
     for all routes to it. possibly a second default for DHCP routes.
+  - allow Name= to be specified repeatedly in the [Match] section. Maybe also
+    support Name=foo*|bar*|baz ?
 
 * resolved:
   - put networkd events and rtnl events at a higher priority, so that
@@ -167,8 +182,6 @@
 
 * journalctl: add the ability to look for the most recent process of a binary. journalctl /usr/bin/X11 --pid=-1 or so...
 
-* set NOTIFY_SOCKET also for control processes
-
 * mount_cgroup_controllers(): symlinks need to get the label applied
 
 * For timer units: add some mechanisms so that timer units that trigger immediately on boot do not have the services
@@ -294,7 +307,6 @@
        - kdbus mapping
        - NameLost/NameAcquired obsolete
        - GVariant
-       - "const" properties (posted)
        - path escaping
   - update systemd.special(7) to mention that dbus.socket is only about the compatibility socket now
   - test bloom filter generation indexes
@@ -773,8 +785,10 @@
 
 * register catalog database signature as file magic
 
-* zsh shell completion: <command> <verb> -<TAB> should complete options, but currently
-  does not
+* zsh shell completion:
+  - <command> <verb> -<TAB> should complete options, but currently does not
+  - systemctl add-wants,add-requires
+
 
 Regularly:
 
diff -urN systemd-216/tools/make-man-rules.py systemd-217/tools/make-man-rules.py
--- systemd-216/tools/make-man-rules.py	2014-06-20 05:37:11.281730275 -0700
+++ systemd-217/tools/make-man-rules.py	1969-12-31 16:00:00.000000000 -0800
@@ -1,127 +0,0 @@
-#  -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
-#
-#  This file is part of systemd.
-#
-#  Copyright 2013 Zbigniew Jędrzejewski-Szmek
-#
-#  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/>.
-
-from __future__ import print_function
-import collections
-import sys
-import os.path
-from xml_helper import *
-
-SECTION = '''\
-MANPAGES += \\
-	{manpages}
-MANPAGES_ALIAS += \\
-	{aliases}
-{rules}
-{htmlrules}
-'''
-
-CONDITIONAL = '''\
-if {conditional}
-''' \
-+ SECTION + \
-'''\
-endif
-'''
-
-HEADER = '''\
-# Do not edit. Generated by make-man-rules.py.
-# To regenerate:
-#   1. Create, update, or remove source .xml files in man/
-#   2. Run 'make update-man-list'
-#   3. Run 'make man' to generate manpages
-#
-# To make a man page conditional on a configure switch add
-# attribute conditional="ENABLE_WHAT" or conditional="WITH_WHAT"
-# to <refentry> element.
-'''
-
-HTML_ALIAS_RULE = '''\
-{}.html: {}.html
-	$(html-alias)
-'''
-
-FOOTER = '''\
-
-# Really, do not edit this file.
-
-EXTRA_DIST += \\
-	{files}
-'''
-
-def man(page, number):
-    return 'man/{}.{}'.format(page, number)
-
-def xml(file):
-    return 'man/{}'.format(os.path.basename(file))
-
-def add_rules(rules, name):
-    xml = xml_parse(name)
-    # print('parsing {}'.format(name), file=sys.stderr)
-    if xml.getroot().tag != 'refentry':
-        return
-    conditional = xml.getroot().get('conditional') or ''
-    rulegroup = rules[conditional]
-    refmeta = xml.find('./refmeta')
-    title = refmeta.find('./refentrytitle').text
-    number = refmeta.find('./manvolnum').text
-    refnames = xml.findall('./refnamediv/refname')
-    target = man(refnames[0].text, number)
-    if title != refnames[0].text:
-        raise ValueError('refmeta and refnamediv disagree: ' + name)
-    for refname in refnames:
-        assert all(refname not in group
-                   for group in rules.values()), "duplicate page name"
-        alias = man(refname.text, number)
-        rulegroup[alias] = target
-        # print('{} => {} [{}]'.format(alias, target, conditional), file=sys.stderr)
-
-def create_rules(xml_files):
-    " {conditional => {alias-name => source-name}} "
-    rules = collections.defaultdict(dict)
-    for name in xml_files:
-        try:
-            add_rules(rules, name)
-        except Exception:
-            print("Failed to process", name, file=sys.stderr)
-            raise
-    return rules
-
-def mjoin(files):
-    return ' \\\n\t'.join(sorted(files) or '#')
-
-def make_makefile(rules, files):
-    return HEADER + '\n'.join(
-        (CONDITIONAL if conditional else SECTION).format(
-            manpages=mjoin(set(rulegroup.values())),
-            aliases=mjoin(k for k,v in rulegroup.items() if k != v),
-            rules='\n'.join('{}: {}'.format(k,v)
-                            for k,v in sorted(rulegroup.items())
-                            if k != v),
-            htmlrules='\n'.join(HTML_ALIAS_RULE.format(k[:-2],v[:-2])
-                                for k,v in sorted(rulegroup.items())
-                                if k != v),
-            conditional=conditional)
-        for conditional,rulegroup in sorted(rules.items())
-        ) + FOOTER.format(files=mjoin(sorted(files)))
-
-if __name__ == '__main__':
-    rules = create_rules(sys.argv[1:])
-    files = (xml(file) for file in sys.argv[1:])
-    print(make_makefile(rules, files), end='')
diff -urN systemd-216/units/basic.target systemd-217/units/basic.target
--- systemd-216/units/basic.target	2014-06-29 13:27:07.761305646 -0700
+++ systemd-217/units/basic.target	2014-11-03 09:33:49.254181570 -0800
@@ -8,6 +8,8 @@
 [Unit]
 Description=Basic System
 Documentation=man:systemd.special(7)
+
 Requires=sysinit.target
+After=sysinit.target
 Wants=sockets.target timers.target paths.target slices.target
-After=sysinit.target sockets.target timers.target paths.target slices.target
+After=sockets.target paths.target slices.target
diff -urN systemd-216/units/systemd-firstboot.service.in systemd-217/units/systemd-firstboot.service.in
--- systemd-216/units/systemd-firstboot.service.in	2014-11-03 09:35:23.975136641 -0800
+++ systemd-217/units/systemd-firstboot.service.in	2014-11-03 09:33:48.263171578 -0800
@@ -10,8 +10,9 @@
 Documentation=man:systemd-firstboot(1)
 DefaultDependencies=no
 Conflicts=shutdown.target
-After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service systemd-sysusers.service
-Before=sysinit.target shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service
+After=systemd-remount-fs.service
+Before=systemd-sysusers.service sysinit.target shutdown.target
 ConditionPathIsReadWrite=/etc
 ConditionFirstBoot=yes
 
diff -urN systemd-216/units/systemd-journald.service.in systemd-217/units/systemd-journald.service.in
--- systemd-216/units/systemd-journald.service.in	2014-06-12 16:15:55.948827245 -0700
+++ systemd-217/units/systemd-journald.service.in	2014-10-22 10:12:06.748818217 -0700
@@ -20,7 +20,7 @@
 RestartSec=0
 NotifyAccess=all
 StandardOutput=null
-CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID
+CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_MAC_OVERRIDE
 WatchdogSec=1min
 
 # Increase the default a bit in order to allow many simultaneous
diff -urN systemd-216/units/systemd-journal-flush.service.in systemd-217/units/systemd-journal-flush.service.in
--- systemd-216/units/systemd-journal-flush.service.in	2013-08-13 13:02:52.811756297 -0700
+++ systemd-217/units/systemd-journal-flush.service.in	2014-11-03 09:33:49.273181762 -0800
@@ -6,13 +6,16 @@
 #  (at your option) any later version.
 
 [Unit]
-Description=Trigger Flushing of Journal to Persistent Storage
+Description=Flush Journal to Persistent Storage
 Documentation=man:systemd-journald.service(8) man:journald.conf(5)
 DefaultDependencies=no
 Requires=systemd-journald.service
-After=systemd-journald.service local-fs.target remote-fs.target
-Before=systemd-user-sessions.service
+After=systemd-journald.service
+After=systemd-remount-fs.service
+Before=systemd-user-sessions.service systemd-tmpfiles-setup.service
+RequiresMountsFor=/var/log/journal
 
 [Service]
-ExecStart=@rootbindir@/systemctl kill --kill-who=main --signal=SIGUSR1 systemd-journald.service
+ExecStart=@rootbindir@/journalctl --flush
 Type=oneshot
+RemainAfterExit=yes
diff -urN systemd-216/units/systemd-tmpfiles-setup-dev.service.in systemd-217/units/systemd-tmpfiles-setup-dev.service.in
--- systemd-216/units/systemd-tmpfiles-setup-dev.service.in	2014-07-03 18:24:41.951585641 -0700
+++ systemd-217/units/systemd-tmpfiles-setup-dev.service.in	2014-11-03 09:33:48.265171598 -0800
@@ -17,4 +17,4 @@
 [Service]
 Type=oneshot
 RemainAfterExit=yes
-ExecStart=@rootbindir@/systemd-tmpfiles --prefix=/dev --create
+ExecStart=@rootbindir@/systemd-tmpfiles --prefix=/dev --create --boot
diff -urN systemd-216/units/systemd-udev-hwdb-update.service.in systemd-217/units/systemd-udev-hwdb-update.service.in
--- systemd-216/units/systemd-udev-hwdb-update.service.in	2014-06-16 03:24:44.204292022 -0700
+++ systemd-217/units/systemd-udev-hwdb-update.service.in	2014-11-03 09:33:48.265171598 -0800
@@ -13,6 +13,9 @@
 After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
 Before=sysinit.target shutdown.target systemd-update-done.service
 ConditionNeedsUpdate=/etc
+ConditionPathExists=|!@udevlibexecdir@/hwdb.bin
+ConditionPathExists=|/etc/udev/hwdb.bin
+ConditionDirectoryNotEmpty=|/etc/udev/hwdb.d/
 
 [Service]
 Type=oneshot
diff -urN systemd-216/units/timers.target systemd-217/units/timers.target
--- systemd-216/units/timers.target	2013-08-13 13:02:52.832756455 -0700
+++ systemd-217/units/timers.target	2014-11-03 09:33:49.254181570 -0800
@@ -8,3 +8,6 @@
 [Unit]
 Description=Timers
 Documentation=man:systemd.special(7)
+
+DefaultDependencies=no
+Conflicts=shutdown.target
diff -urN systemd-216/units/user/systemd-bus-proxyd@.service systemd-217/units/user/systemd-bus-proxyd@.service
--- systemd-216/units/user/systemd-bus-proxyd@.service	2014-06-10 11:56:56.007071476 -0700
+++ systemd-217/units/user/systemd-bus-proxyd@.service	1969-12-31 16:00:00.000000000 -0800
@@ -1,16 +0,0 @@
-#  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.
-
-[Unit]
-Description=Legacy D-Bus Protocol Compatibility Daemon
-
-[Service]
-# The first argument will be replaced by the service by information on
-# the process requesting the proxy, we need a placeholder to keep the
-# space available for this.
-ExecStart=/usr/lib/systemd/systemd-bus-proxyd --address=kernel:path=/dev/kdbus/%U-user/bus --configuration=/etc/dbus-1/session.conf --configuration=/etc/dbus-1/session-local.conf --configuration=/etc/dbus-1/session.d/ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-NotifyAccess=main
diff -urN systemd-216/units/user/systemd-bus-proxyd@.service.in systemd-217/units/user/systemd-bus-proxyd@.service.in
--- systemd-216/units/user/systemd-bus-proxyd@.service.in	1969-12-31 16:00:00.000000000 -0800
+++ systemd-217/units/user/systemd-bus-proxyd@.service.in	2014-06-10 10:34:34.383820356 -0700
@@ -0,0 +1,16 @@
+#  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.
+
+[Unit]
+Description=Legacy D-Bus Protocol Compatibility Daemon
+
+[Service]
+# The first argument will be replaced by the service by information on
+# the process requesting the proxy, we need a placeholder to keep the
+# space available for this.
+ExecStart=@rootlibexecdir@/systemd-bus-proxyd --address=kernel:path=/dev/kdbus/%U-user/bus --configuration=/etc/dbus-1/session.conf --configuration=/etc/dbus-1/session-local.conf --configuration=/etc/dbus-1/session.d/ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+NotifyAccess=main
diff -urN systemd-216/units/user/systemd-consoled.service.in systemd-217/units/user/systemd-consoled.service.in
--- systemd-216/units/user/systemd-consoled.service.in	2014-11-03 09:35:35.094248755 -0800
+++ systemd-217/units/user/systemd-consoled.service.in	1969-12-31 16:00:00.000000000 -0800
@@ -1,15 +0,0 @@
-#  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.
-
-[Unit]
-Description=Console Manager and Terminal Emulator
-
-[Service]
-Type=notify
-Restart=always
-RestartSec=0
-ExecStart=@rootlibexecdir@/systemd-consoled
