summary refs log tree commit diff
path: root/pkgs/os-specific/linux
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/os-specific/linux')
-rw-r--r--pkgs/os-specific/linux/kernel-headers/3.14.nix71
-rw-r--r--pkgs/os-specific/linux/kernel-headers/3.18.nix (renamed from pkgs/os-specific/linux/kernel-headers/3.12.nix)4
-rw-r--r--pkgs/os-specific/linux/kernel/linux-3.10.nix17
-rw-r--r--pkgs/os-specific/linux/kernel/linux-3.12.nix17
-rw-r--r--pkgs/os-specific/linux/kernel/linux-3.14.nix18
-rw-r--r--pkgs/os-specific/linux/libcap-ng/default.nix34
-rw-r--r--pkgs/os-specific/linux/miraclecast/default.nix26
-rw-r--r--pkgs/os-specific/linux/nvidiabl/default.nix2
-rw-r--r--pkgs/os-specific/linux/nvidiabl/linux4compat.patch22
-rw-r--r--pkgs/os-specific/linux/systemd/default.nix55
-rw-r--r--pkgs/os-specific/linux/systemd/fixes.patch2569
-rw-r--r--pkgs/os-specific/linux/udisks/2-default.nix6
-rw-r--r--pkgs/os-specific/linux/upower/default.nix4
-rw-r--r--pkgs/os-specific/linux/util-linux/default.nix8
-rw-r--r--pkgs/os-specific/linux/util-linux/rtcwake-search-PATH-for-shutdown.patch22
15 files changed, 79 insertions, 2796 deletions
diff --git a/pkgs/os-specific/linux/kernel-headers/3.14.nix b/pkgs/os-specific/linux/kernel-headers/3.14.nix
deleted file mode 100644
index d9d0ce7e3b3..00000000000
--- a/pkgs/os-specific/linux/kernel-headers/3.14.nix
+++ /dev/null
@@ -1,71 +0,0 @@
-{ stdenv, fetchurl, perl, cross ? null }:
-
-assert cross == null -> stdenv.isLinux;
-
-let
-
-  version = "3.14.1";
-
-  kernelHeadersBaseConfig =
-    if cross == null
-    then stdenv.platform.kernelHeadersBaseConfig
-    else cross.platform.kernelHeadersBaseConfig;
-
-in
-
-stdenv.mkDerivation {
-  name = "linux-headers-${version}";
-
-  src = fetchurl {
-    url = "mirror://kernel/linux/kernel/v3.x/linux-${version}.tar.xz";
-    sha256 = "1njm8gvlj7cq0m1051yxszl4f63383a7sv1na13hkqkv36kipgqx";
-  };
-
-  targetConfig = if cross != null then cross.config else null;
-
-  platform =
-    if cross != null then cross.platform.kernelArch else
-    if stdenv.system == "i686-linux" then "i386" else
-    if stdenv.system == "x86_64-linux" then "x86_64" else
-    if stdenv.system == "powerpc-linux" then "powerpc" else
-    if stdenv.isArm then "arm" else
-    if stdenv.platform ? kernelArch then stdenv.platform.kernelArch else
-    abort "don't know what the kernel include directory is called for this platform";
-
-  buildInputs = [perl];
-
-  extraIncludeDirs =
-    if cross != null then
-        (if cross.arch == "powerpc" then ["ppc"] else [])
-    else if stdenv.system == "powerpc-linux" then ["ppc"] else [];
-
-  buildPhase = ''
-    if test -n "$targetConfig"; then
-       export ARCH=$platform
-    fi
-    make ${kernelHeadersBaseConfig} SHELL=bash
-    make mrproper headers_check SHELL=bash
-  '';
-
-  installPhase = ''
-    make INSTALL_HDR_PATH=$out headers_install
-
-    # Some builds (e.g. KVM) want a kernel.release.
-    mkdir -p $out/include/config
-    echo "${version}-default" > $out/include/config/kernel.release
-  '';
-
-  # !!! hacky
-  fixupPhase = ''
-    ln -s asm $out/include/asm-$platform
-    if test "$platform" = "i386" -o "$platform" = "x86_64"; then
-      ln -s asm $out/include/asm-x86
-    fi
-  '';
-
-  meta = with stdenv.lib; {
-    description = "Header files and scripts for Linux kernel";
-    license = licenses.gpl2;
-    platforms = platforms.linux;
-  };
-}
diff --git a/pkgs/os-specific/linux/kernel-headers/3.12.nix b/pkgs/os-specific/linux/kernel-headers/3.18.nix
index 2fd34c68edc..0cc38a0548c 100644
--- a/pkgs/os-specific/linux/kernel-headers/3.12.nix
+++ b/pkgs/os-specific/linux/kernel-headers/3.18.nix
@@ -4,7 +4,7 @@ assert cross == null -> stdenv.isLinux;
 
 let
 
-  version = "3.12.32";
+  version = "3.18.14";
 
   kernelHeadersBaseConfig =
     if cross == null
@@ -18,7 +18,7 @@ stdenv.mkDerivation {
 
   src = fetchurl {
     url = "mirror://kernel/linux/kernel/v3.x/linux-${version}.tar.xz";
-    sha256 = "1hzws2bf267hfk81ywqcxspkyi1lg56x63izdc0pv1338xcfas53";
+    sha256 = "1xh0vvn1l2g1kkg54f0mg0inbpsiqs24ybgsakksmcpcadjgqk1i";
   };
 
   targetConfig = if cross != null then cross.config else null;
diff --git a/pkgs/os-specific/linux/kernel/linux-3.10.nix b/pkgs/os-specific/linux/kernel/linux-3.10.nix
deleted file mode 100644
index a231b551dc0..00000000000
--- a/pkgs/os-specific/linux/kernel/linux-3.10.nix
+++ /dev/null
@@ -1,17 +0,0 @@
-{ stdenv, fetchurl, perl, buildLinux, ... } @ args:
-
-import ./generic.nix (args // rec {
-  version = "3.10.92";
-  extraMeta.branch = "3.10";
-
-  src = fetchurl {
-    url = "mirror://kernel/linux/kernel/v3.x/linux-${version}.tar.xz";
-    sha256 = "0z0jdix1mfpnnc8cxw7rzpnhxdayckpnrasvxi1qf0dwhcqgk92d";
-  };
-
-  features.iwlwifi = true;
-  features.efiBootStub = true;
-  features.needsCifsUtils = true;
-  features.canDisableNetfilterConntrackHelpers = true;
-  features.netfilterRPFilter = true;
-})
diff --git a/pkgs/os-specific/linux/kernel/linux-3.12.nix b/pkgs/os-specific/linux/kernel/linux-3.12.nix
deleted file mode 100644
index 7ed6cd142d1..00000000000
--- a/pkgs/os-specific/linux/kernel/linux-3.12.nix
+++ /dev/null
@@ -1,17 +0,0 @@
-{ stdenv, fetchurl, perl, buildLinux, ... } @ args:
-
-import ./generic.nix (args // rec {
-  version = "3.12.50";
-  extraMeta.branch = "3.12";
-
-  src = fetchurl {
-    url = "mirror://kernel/linux/kernel/v3.x/linux-${version}.tar.xz";
-    sha256 = "1bn07wsrcbg4qgqd4v2810c3qc0ifbcza0fyj8s54yd78g9qj4lj";
-  };
-
-  features.iwlwifi = true;
-  features.efiBootStub = true;
-  features.needsCifsUtils = true;
-  features.canDisableNetfilterConntrackHelpers = true;
-  features.netfilterRPFilter = true;
-})
diff --git a/pkgs/os-specific/linux/kernel/linux-3.14.nix b/pkgs/os-specific/linux/kernel/linux-3.14.nix
deleted file mode 100644
index afb4437459b..00000000000
--- a/pkgs/os-specific/linux/kernel/linux-3.14.nix
+++ /dev/null
@@ -1,18 +0,0 @@
-{ stdenv, fetchurl, perl, buildLinux, ... } @ args:
-
-import ./generic.nix (args // rec {
-  version = "3.14.56";
-  # Remember to update grsecurity!
-  extraMeta.branch = "3.14";
-
-  src = fetchurl {
-    url = "mirror://kernel/linux/kernel/v3.x/linux-${version}.tar.xz";
-    sha256 = "1ggvjrz51nfhj7amn3v2nd0b0x8dnz68k9cldzl729cqp9gsc3hf";
-  };
-
-  features.iwlwifi = true;
-  features.efiBootStub = true;
-  features.needsCifsUtils = true;
-  features.canDisableNetfilterConntrackHelpers = true;
-  features.netfilterRPFilter = true;
-} // (args.argsOverride or {}))
diff --git a/pkgs/os-specific/linux/libcap-ng/default.nix b/pkgs/os-specific/linux/libcap-ng/default.nix
index 3670f06e543..ea54f1a39fd 100644
--- a/pkgs/os-specific/linux/libcap-ng/default.nix
+++ b/pkgs/os-specific/linux/libcap-ng/default.nix
@@ -1,22 +1,40 @@
-{ stdenv, fetchurl, python }:
+{ stdenv, fetchurl, swig ? null, python2 ? null, python3 ? null }:
 
-assert stdenv.isLinux;
+assert python2 != null || python3 != null -> swig != null;
 
 stdenv.mkDerivation rec {
   name = "libcap-ng-${version}";
-  version = "0.7.3";
+  # When updating make sure to test that the version with
+  # all of the python bindings still works
+  version = "0.7.7";
 
   src = fetchurl {
     url = "${meta.homepage}/${name}.tar.gz";
-    sha256 = "1cavlcrpqi4imkmagjhw65br8rv2fsbhf68mm3lczr51sg44392w";
+    sha256 = "0syhyrixk7fqvwis3k7iddn75g0qxysc1q5fifvzccxk7774jmb1";
   };
 
-  buildInputs = [ python ]; # ToDo? optional swig for python bindings
+  nativeBuildInputs = [ swig ];
+  buildInputs = [ python2 python3 ];
 
-  meta = {
+  postPatch = ''
+    function get_header() {
+      echo -e "#include <$1>" | gcc -M -xc - | tr ' ' '\n' | grep "$1" | head -n 1
+    }
+
+    # Fix some hardcoding of header paths
+    sed -i "s,/usr/include/linux/capability.h,$(get_header linux/capability.h),g" bindings/python{,3}/Makefile.in
+  '';
+
+  configureFlags = [
+    (if python2 != null then "--with-python" else "--without-python")
+    (if python3 != null then "--with-python3" else "--without-python3")
+  ];
+
+  meta = let inherit (stdenv.lib) platforms licenses maintainers; in {
     description = "Library for working with POSIX capabilities";
     homepage = http://people.redhat.com/sgrubb/libcap-ng/;
-    platforms = stdenv.lib.platforms.linux;
-    license = stdenv.lib.licenses.lgpl21;
+    platforms = platforms.linux;
+    license = licenses.lgpl21;
+    maintainers = with maintainers; [ wkennington ];
   };
 }
diff --git a/pkgs/os-specific/linux/miraclecast/default.nix b/pkgs/os-specific/linux/miraclecast/default.nix
deleted file mode 100644
index 3d5a76144af..00000000000
--- a/pkgs/os-specific/linux/miraclecast/default.nix
+++ /dev/null
@@ -1,26 +0,0 @@
-{ stdenv, fetchFromGitHub, autoreconfHook, pkgconfig, udev, systemd, glib, readline }:
-
-with stdenv.lib;
-stdenv.mkDerivation rec {
-  name = "miraclecast-0.0-git-20151002";
-
-  src = fetchFromGitHub {
-    owner = "albfan";
-    repo = "miraclecast";
-    rev = "30b8c2d22391423f76ba582aaaa1e0936869103a";
-    sha256 = "0i076n76kq64fayc7v06gr1853pk5r6ms86m57vd1xsjd0r9wyxd";
-  };
-
-  # INFO: It is important to list 'systemd' first as for now miraclecast
-  # links against a customized systemd. Otherwise, a systemd package from
-  # a propagatedBuildInput could take precedence.
-  buildInputs = [ systemd autoreconfHook pkgconfig udev glib readline ];
-
-  meta = {
-    homepage = https://github.com/albfan/miraclecast;
-    description = "Connect external monitors via Wi-Fi";
-    license = licenses.lgpl21Plus;
-    maintainers = with maintainers; [ tstrobel ];
-    platforms = platforms.linux;
-  };
-}
diff --git a/pkgs/os-specific/linux/nvidiabl/default.nix b/pkgs/os-specific/linux/nvidiabl/default.nix
index a6797608664..a5a43926e04 100644
--- a/pkgs/os-specific/linux/nvidiabl/default.nix
+++ b/pkgs/os-specific/linux/nvidiabl/default.nix
@@ -8,8 +8,6 @@ stdenv.mkDerivation {
     sha256 = "1c7ar39wc8jpqh67sw03lwnyp0m9l6dad469ybqrgcywdiwxspwj";
   };
 
-  patches = [ ./linux4compat.patch ];
-
   preConfigure = ''
     sed -i 's|/sbin/depmod|#/sbin/depmod|' Makefile
   '';
diff --git a/pkgs/os-specific/linux/nvidiabl/linux4compat.patch b/pkgs/os-specific/linux/nvidiabl/linux4compat.patch
deleted file mode 100644
index ad8236a2b63..00000000000
--- a/pkgs/os-specific/linux/nvidiabl/linux4compat.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 2bf6f08b2492cc04a2c39fdcb22a2d0c18963d1c Mon Sep 17 00:00:00 2001
-From: sonic414 <sonic414@gmail.com>
-Date: Tue, 28 Apr 2015 19:30:15 +0530
-Subject: [PATCH] strnicmp to strncasecmp in Linux 4.0.0
-
----
- nvidiabl-module.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/nvidiabl-module.c b/nvidiabl-module.c
-index b789ea4..b306579 100644
---- a/nvidiabl-module.c
-+++ b/nvidiabl-module.c
-@@ -214,7 +214,7 @@ static int __init nvidiabl_init(void)
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
- 	
- 	for (iii = 0 ; iii < sizeof(backlight_type_ids) ; iii++) {
--		if (strnicmp(bl_type, backlight_type_ids[iii].id, sizeof(bl_type)) == 0) {
-+		if (strncasecmp(bl_type, backlight_type_ids[iii].id, sizeof(bl_type)) == 0) {
- 			props.type = backlight_type_ids[iii].type;
- 			printk(KERN_INFO "nvidiabl: backlight type is %s\n", backlight_type_ids[iii].id);
- 		}
diff --git a/pkgs/os-specific/linux/systemd/default.nix b/pkgs/os-specific/linux/systemd/default.nix
index 5e458693799..b4588e3d17f 100644
--- a/pkgs/os-specific/linux/systemd/default.nix
+++ b/pkgs/os-specific/linux/systemd/default.nix
@@ -1,9 +1,9 @@
-{ stdenv, fetchurl, pkgconfig, intltool, gperf, libcap, dbus, kmod
+{ stdenv, fetchFromGitHub, pkgconfig, intltool, gperf, libcap, dbus, kmod
 , xz, pam, acl, cryptsetup, libuuid, m4, utillinux
 , glib, kbd, libxslt, coreutils, libgcrypt
-, kexectools, libmicrohttpd, linuxHeaders
+, kexectools, libmicrohttpd, linuxHeaders, libseccomp
+, autoreconfHook, gettext, docbook_xsl, docbook_xml_dtd_42, docbook_xml_dtd_45
 , pythonPackages ? null, pythonSupport ? false
-, enableKDbus ? false
 }:
 
 assert stdenv.isLinux;
@@ -11,24 +11,26 @@ assert stdenv.isLinux;
 assert pythonSupport -> pythonPackages != null;
 
 stdenv.mkDerivation rec {
-  version = "217";
+  version = "227";
   name = "systemd-${version}";
 
-  src = fetchurl {
-    url = "http://www.freedesktop.org/software/systemd/${name}.tar.xz";
-    sha256 = "163l1y4p2a564d4ynfq3k3xf53j2v5s81blb6cvpn1y7rpxyccd0";
+  src = fetchFromGitHub {
+    owner = "NixOS";
+    repo = "systemd";
+    rev = "7d94d27801d20278103d8c146633fe81e06697d6";
+    sha256 = "0cvzsrazqgbia3zajb0z4ik8myfil4bdy2c29qs6w93d6yvrjfkj";
   };
 
-  patches =
-    [ # These are all changes between upstream and
-      # https://github.com/NixOS/systemd/tree/nixos-v217.
-      ./fixes.patch
-    ];
+  outputs = [ "out" "man" "doc" ];
 
   buildInputs =
-    [ pkgconfig intltool gperf libcap kmod xz pam acl
+    [ linuxHeaders pkgconfig intltool gperf libcap kmod xz pam acl
       /* cryptsetup */ libuuid m4 glib libxslt libgcrypt
-      libmicrohttpd linuxHeaders
+      libmicrohttpd kexectools libseccomp
+      /* FIXME: we may be able to prevent the following dependencies
+         by generating an autoconf'd tarball, but that's probably not
+         worth it. */
+      autoreconfHook gettext docbook_xsl docbook_xml_dtd_42 docbook_xml_dtd_45
     ] ++ stdenv.lib.optionals pythonSupport [pythonPackages.python pythonPackages.lxml];
 
   configureFlags =
@@ -38,7 +40,6 @@ stdenv.mkDerivation rec {
       "--with-kbd-loadkeys=${kbd}/bin/loadkeys"
       "--with-kbd-setfont=${kbd}/bin/setfont"
       "--with-rootprefix=$(out)"
-      "--with-dbusinterfacedir=$(out)/share/dbus-1/interfaces"
       "--with-dbuspolicydir=$(out)/etc/dbus-1/system.d"
       "--with-dbussystemservicedir=$(out)/share/dbus-1/system-services"
       "--with-dbussessionservicedir=$(out)/share/dbus-1/services"
@@ -51,22 +52,27 @@ stdenv.mkDerivation rec {
       "--disable-sysusers"
       "--disable-timedated"
       "--enable-timesyncd"
-      "--disable-readahead"
       "--disable-firstboot"
       "--disable-localed"
       "--enable-resolved"
       "--disable-split-usr"
+      "--disable-libcurl"
+      "--disable-libidn"
+      "--disable-quotacheck"
+      "--disable-ldconfig"
+      "--disable-smack"
 
       "--with-sysvinit-path="
       "--with-sysvrcnd-path="
       "--with-rc-local-script-path-stop=/etc/halt.local"
-    ] ++ stdenv.lib.optional enableKDbus "--enable-kdbus";
+    ];
 
   preConfigure =
     ''
+      ./autogen.sh
+
       # FIXME: patch this in systemd properly (and send upstream).
-      # FIXME: use sulogin from util-linux once updated.
-      for i in src/remount-fs/remount-fs.c src/core/mount.c src/core/swap.c src/fsck/fsck.c units/emergency.service.in units/rescue.service.in src/journal/cat.c src/core/shutdown.c src/nspawn/nspawn.c; do
+      for i in src/remount-fs/remount-fs.c src/core/mount.c src/core/swap.c src/fsck/fsck.c units/emergency.service.in units/rescue.service.in src/journal/cat.c src/core/shutdown.c src/nspawn/nspawn.c src/shared/generator.c; do
         test -e $i
         substituteInPlace $i \
           --replace /usr/bin/getent ${stdenv.glibc}/bin/getent \
@@ -77,7 +83,7 @@ stdenv.mkDerivation rec {
           --replace /bin/echo ${coreutils}/bin/echo \
           --replace /bin/cat ${coreutils}/bin/cat \
           --replace /sbin/sulogin ${utillinux}/sbin/sulogin \
-          --replace /sbin/kexec ${kexectools}/sbin/kexec
+          --replace /usr/lib/systemd/systemd-fsck $out/lib/systemd/systemd-fsck
       done
 
       substituteInPlace src/journal/catalog.c \
@@ -86,10 +92,6 @@ stdenv.mkDerivation rec {
       configureFlagsArray+=("--with-ntp-servers=0.nixos.pool.ntp.org 1.nixos.pool.ntp.org 2.nixos.pool.ntp.org 3.nixos.pool.ntp.org")
     '';
 
-  # This is needed because systemd uses the gold linker, which doesn't
-  # yet have the wrapper script to add rpath flags automatically.
-  NIX_LDFLAGS = "-rpath ${pam}/lib -rpath ${libcap}/lib -rpath ${acl}/lib -rpath ${stdenv.cc.cc}/lib";
-
   PYTHON_BINARY = "${coreutils}/bin/env python"; # don't want a build time dependency on Python
 
   NIX_CFLAGS_COMPILE =
@@ -147,6 +149,11 @@ stdenv.mkDerivation rec {
       done
 
       rm -rf $out/etc/rpm
+
+      rm $out/lib/*.la
+
+      # "kernel-install" shouldn't be used on NixOS.
+      find $out -name "*kernel-install*" -exec rm {} \;
     ''; # */
 
   enableParallelBuilding = true;
diff --git a/pkgs/os-specific/linux/systemd/fixes.patch b/pkgs/os-specific/linux/systemd/fixes.patch
deleted file mode 100644
index 2997c02d26d..00000000000
--- a/pkgs/os-specific/linux/systemd/fixes.patch
+++ /dev/null
@@ -1,2569 +0,0 @@
-diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in
-index e30d9a8..a3d399b 100644
---- a/rules/99-systemd.rules.in
-+++ b/rules/99-systemd.rules.in
-@@ -14,10 +14,6 @@ KERNEL=="vport*", TAG+="systemd"
- SUBSYSTEM=="block", KERNEL!="ram*", TAG+="systemd"
- SUBSYSTEM=="block", KERNEL!="ram*", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", ENV{SYSTEMD_READY}="0"
- 
--# Ignore encrypted devices with no identified superblock on it, since
--# we are probably still calling mke2fs or mkswap on it.
--SUBSYSTEM=="block", KERNEL!="ram*", ENV{DM_UUID}=="CRYPT-*", ENV{ID_PART_TABLE_TYPE}=="", ENV{ID_FS_USAGE}=="", ENV{SYSTEMD_READY}="0"
--
- # Ignore raid devices that are not yet assembled and started
- SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", TEST!="md/array_state", ENV{SYSTEMD_READY}="0"
- SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0"
-diff --git a/src/core/job.c b/src/core/job.c
-index eaa4bb1..db44fee 100644
---- a/src/core/job.c
-+++ b/src/core/job.c
-@@ -352,6 +352,9 @@ bool job_type_is_redundant(JobType a, UnitActiveState b) {
-                 return
-                         b == UNIT_ACTIVATING;
- 
-+        case JOB_NOP:
-+                return true;
-+
-         default:
-                 assert_not_reached("Invalid job type");
-         }
-diff --git a/src/core/job.h b/src/core/job.h
-index 1e7c61b..ee8e54a 100644
---- a/src/core/job.h
-+++ b/src/core/job.h
-@@ -49,9 +49,11 @@ enum JobType {
-         _JOB_TYPE_MAX_MERGING,
- 
-         /* JOB_NOP can enter into a transaction, but as it won't pull in
--         * any dependencies, it won't have to merge with anything.
--         * job_install() avoids the problem of merging JOB_NOP too (it's
--         * special-cased, only merges with other JOB_NOPs). */
-+         * any dependencies and it uses the special 'nop_job' slot in Unit,
-+         * it won't have to merge with anything (except possibly into another
-+         * JOB_NOP, previously installed). JOB_NOP is special-cased in
-+         * job_type_is_*() functions so that the transaction can be
-+         * activated. */
-         JOB_NOP = _JOB_TYPE_MAX_MERGING, /* do nothing */
- 
-         _JOB_TYPE_MAX_IN_TRANSACTION,
-@@ -190,11 +192,15 @@ _pure_ static inline bool job_type_is_mergeable(JobType a, JobType b) {
- }
- 
- _pure_ static inline bool job_type_is_conflicting(JobType a, JobType b) {
--        return !job_type_is_mergeable(a, b);
-+        return a != JOB_NOP && b != JOB_NOP && !job_type_is_mergeable(a, b);
- }
- 
- _pure_ static inline bool job_type_is_superset(JobType a, JobType b) {
-         /* Checks whether operation a is a "superset" of b in its actions */
-+        if (b == JOB_NOP)
-+                return true;
-+        if (a == JOB_NOP)
-+                return false;
-         return a == job_type_lookup_merge(a, b);
- }
- 
-diff --git a/src/core/manager.c b/src/core/manager.c
-index d427d88..256d6f7 100644
---- a/src/core/manager.c
-+++ b/src/core/manager.c
-@@ -662,9 +662,11 @@ static int manager_setup_notify(Manager *m) {
-                         return -errno;
-                 }
- 
--                if (m->running_as == SYSTEMD_SYSTEM)
-+                if (m->running_as == SYSTEMD_SYSTEM) {
-                         m->notify_socket = strdup("/run/systemd/notify");
--                else {
-+                        if (!m->notify_socket)
-+                                return log_oom();
-+                } else {
-                         const char *e;
- 
-                         e = getenv("XDG_RUNTIME_DIR");
-@@ -674,9 +676,11 @@ static int manager_setup_notify(Manager *m) {
-                         }
- 
-                         m->notify_socket = strappend(e, "/systemd/notify");
-+                        if (!m->notify_socket)
-+                                return log_oom();
-+
-+                        mkdir_parents_label(m->notify_socket, 0755);
-                 }
--                if (!m->notify_socket)
--                        return log_oom();
- 
-                 strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1);
-                 r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
-diff --git a/src/core/shutdown.c b/src/core/shutdown.c
-index 20cf526..03cfddc 100644
---- a/src/core/shutdown.c
-+++ b/src/core/shutdown.c
-@@ -75,7 +75,9 @@ static int parse_argv(int argc, char *argv[]) {
-         assert(argc >= 1);
-         assert(argv);
- 
--        while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
-+        /* "-" prevents getopt from permuting argv[] and moving the verb away
-+         * from argv[1]. Our interface to initrd promises it'll be there. */
-+        while ((c = getopt_long(argc, argv, "-", options, NULL)) >= 0)
-                 switch (c) {
- 
-                 case ARG_LOG_LEVEL:
-@@ -113,6 +115,13 @@ static int parse_argv(int argc, char *argv[]) {
- 
-                         break;
- 
-+                case '\001':
-+                        if (!arg_verb)
-+                                arg_verb = optarg;
-+                        else
-+                                log_error("Excess arguments, ignoring");
-+                        break;
-+
-                 case '?':
-                         return -EINVAL;
- 
-@@ -120,15 +129,11 @@ static int parse_argv(int argc, char *argv[]) {
-                         assert_not_reached("Unhandled option code.");
-                 }
- 
--        if (optind >= argc) {
-+        if (!arg_verb) {
-                 log_error("Verb argument missing.");
-                 return -EINVAL;
-         }
- 
--        arg_verb = argv[optind];
--
--        if (optind + 1 < argc)
--                log_error("Excess arguments, ignoring");
-         return 0;
- }
- 
-diff --git a/src/core/snapshot.c b/src/core/snapshot.c
-index 5eed615..c2678cb 100644
---- a/src/core/snapshot.c
-+++ b/src/core/snapshot.c
-@@ -208,7 +208,7 @@ int snapshot_create(Manager *m, const char *name, bool cleanup, sd_bus_error *e,
-                         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 --git a/src/core/systemd.pc.in b/src/core/systemd.pc.in
-index d5b86bf..9c66e7b 100644
---- a/src/core/systemd.pc.in
-+++ b/src/core/systemd.pc.in
-@@ -14,8 +14,8 @@ systemduserunitdir=@userunitdir@
- systemduserpresetdir=@userpresetdir@
- systemdsystemconfdir=@pkgsysconfdir@/system
- systemduserconfdir=@pkgsysconfdir@/user
--systemdsystemunitpath=${systemdsystemconfdir}:/etc/systemd/system:/run/systemd/system:/usr/local/lib/systemd/system:${systemdsystemunitdir}:/usr/lib/systemd/system:/lib/systemd/system
--systemduserunitpath=${systemduserconfdir}:/etc/systemd/user:/run/systemd/user:/usr/local/lib/systemd/user:/usr/local/share/systemd/user:${systemduserunitdir}:/usr/lib/systemd/user:/usr/share/systemd/user
-+systemdsystemunitpath=${systemdsystemconfdir}:/etc/systemd/system:/etc/systemd-mutable/system:/nix/var/nix/profiles/default/lib/systemd/user:/run/systemd/system:${systemdsystemunitdir}
-+systemduserunitpath=${systemduserconfdir}:/etc/systemd/user:/etc/systemd-mutable/user:/nix/var/nix/profiles/default/lib/systemd/system:/run/systemd/user:${systemduserunitdir}
- systemdsystemgeneratordir=@systemgeneratordir@
- systemdusergeneratordir=@usergeneratordir@
- systemdsleepdir=@systemsleepdir@
-diff --git a/src/core/timer.c b/src/core/timer.c
-index a3713e2..5c4e9f9 100644
---- a/src/core/timer.c
-+++ b/src/core/timer.c
-@@ -521,6 +521,7 @@ fail:
- 
- static int timer_start(Unit *u) {
-         Timer *t = TIMER(u);
-+        TimerValue *v;
- 
-         assert(t);
-         assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED);
-@@ -530,6 +531,11 @@ static int timer_start(Unit *u) {
- 
-         t->last_trigger = DUAL_TIMESTAMP_NULL;
- 
-+        /* Reenable all timers that depend on unit activation time */
-+        LIST_FOREACH(value, v, t->values)
-+                if (v->base == TIMER_ACTIVE)
-+                        v->disabled = false;
-+
-         if (t->stamp_path) {
-                 struct stat st;
- 
-diff --git a/src/core/umount.c b/src/core/umount.c
-index cffa453..4d1a9ff 100644
---- a/src/core/umount.c
-+++ b/src/core/umount.c
-@@ -385,6 +385,8 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
-                  * anyway, since we are running from it. They have
-                  * already been remounted ro. */
-                 if (path_equal(m->path, "/")
-+                    || path_equal(m->path, "/nix")
-+                    || path_equal(m->path, "/nix/store")
- #ifndef HAVE_SPLIT_USR
-                     || path_equal(m->path, "/usr")
- #endif
-diff --git a/src/delta/delta.c b/src/delta/delta.c
-index 25c4a0b..e1f2d6d 100644
---- a/src/delta/delta.c
-+++ b/src/delta/delta.c
-@@ -487,7 +487,7 @@ static int parse_flags(const char *flag_str, int flags) {
-         const char *word, *state;
-         size_t l;
- 
--        FOREACH_WORD(word, l, flag_str, state) {
-+        FOREACH_WORD_SEPARATOR(word, l, flag_str, ",", state) {
-                 if (strneq("masked", word, l))
-                         flags |= SHOW_MASKED;
-                 else if (strneq ("equivalent", word, l))
-diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
-index 70a5918..a5661e8 100644
---- a/src/fsck/fsck.c
-+++ b/src/fsck/fsck.c
-@@ -315,8 +315,7 @@ int main(int argc, char *argv[]) {
-                         return EXIT_FAILURE;
-                 }
- 
--        cmdline[i++] = "/sbin/fsck";
--        cmdline[i++] =  arg_repair;
-+        cmdline[i++] = "/run/current-system/sw/bin/fsck";
-         cmdline[i++] = "-T";
- 
-         /*
-diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
-index e257c12..1e04553 100644
---- a/src/fstab-generator/fstab-generator.c
-+++ b/src/fstab-generator/fstab-generator.c
-@@ -485,7 +485,7 @@ static int add_usr_mount(void) {
-                         return log_oom();
-         }
- 
--        if (!arg_usr_what || !arg_usr_options)
-+        if (!arg_usr_what)
-                 return 0;
- 
-         what = fstab_node_to_udev_node(arg_usr_what);
-@@ -494,7 +494,13 @@ static int add_usr_mount(void) {
-                 return -1;
-         }
- 
--        opts = arg_usr_options;
-+        if (!arg_usr_options)
-+                opts = arg_root_rw > 0 ? "rw" : "ro";
-+        else if (!mount_test_option(arg_usr_options, "ro") &&
-+                 !mount_test_option(arg_usr_options, "rw"))
-+                opts = strappenda(arg_usr_options, ",", arg_root_rw > 0 ? "rw" : "ro");
-+        else
-+                opts = arg_usr_options;
- 
-         log_debug("Found entry what=%s where=/sysroot/usr type=%s", what, strna(arg_usr_fstype));
-         return add_mount(what,
-diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c
-index e487369..ff4e9c9 100644
---- a/src/hostname/hostnamectl.c
-+++ b/src/hostname/hostnamectl.c
-@@ -536,5 +536,5 @@ int main(int argc, char *argv[]) {
-         r = hostnamectl_main(bus, argc, argv);
- 
- finish:
--        return r < 0 ? EXIT_FAILURE : r;
-+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
- }
-diff --git a/src/journal-remote/journal-remote-parse.c b/src/journal-remote/journal-remote-parse.c
-index 7dd8878..70a9a13 100644
---- a/src/journal-remote/journal-remote-parse.c
-+++ b/src/journal-remote/journal-remote-parse.c
-@@ -344,22 +344,25 @@ int process_data(RemoteSource *source) {
-                    LLLLLLLL0011223344...\n
-                 */
-                 sep = memchr(line, '=', n);
--                if (sep)
-+                if (sep) {
-                         /* chomp newline */
-                         n--;
--                else
-+
-+                        r = iovw_put(&source->iovw, line, n);
-+                        if (r < 0)
-+                                return r;
-+                } else {
-                         /* replace \n with = */
-                         line[n-1] = '=';
--                log_trace("Received: %.*s", (int) n, line);
- 
--                r = iovw_put(&source->iovw, line, n);
--                if (r < 0) {
--                        log_error("Failed to put line in iovect");
--                        return r;
-+                        source->field_len = n;
-+                        source->state = STATE_DATA_START;
-+
-+                        /* we cannot put the field in iovec until we have all data */
-                 }
- 
--                if (!sep)
--                        source->state = STATE_DATA_START;
-+                log_trace("Received: %.*s (%s)", (int) n, line, sep ? "text" : "binary");
-+
-                 return 0; /* continue */
-         }
- 
-@@ -382,6 +385,7 @@ int process_data(RemoteSource *source) {
- 
-         case STATE_DATA: {
-                 void *data;
-+                char *field;
- 
-                 assert(source->data_size > 0);
- 
-@@ -396,11 +400,12 @@ int process_data(RemoteSource *source) {
- 
-                 assert(data);
- 
--                r = iovw_put(&source->iovw, data, source->data_size);
--                if (r < 0) {
--                        log_error("failed to put binary buffer in iovect");
-+                field = (char*) data - sizeof(uint64_t) - source->field_len;
-+                memmove(field + sizeof(uint64_t), field, source->field_len);
-+
-+                r = iovw_put(&source->iovw, field + sizeof(uint64_t), source->field_len + source->data_size);
-+                if (r < 0)
-                         return r;
--                }
- 
-                 source->state = STATE_DATA_FINISH;
- 
-diff --git a/src/journal-remote/journal-remote-parse.h b/src/journal-remote/journal-remote-parse.h
-index 8499f4e..22db550 100644
---- a/src/journal-remote/journal-remote-parse.h
-+++ b/src/journal-remote/journal-remote-parse.h
-@@ -42,7 +42,9 @@ typedef struct RemoteSource {
-         size_t offset;     /* offset to the beginning of live data in the buffer */
-         size_t scanned;    /* number of bytes since the beginning of data without a newline */
-         size_t filled;     /* total number of bytes in the buffer */
--        size_t data_size;  /* size of the binary data chunk being processed */
-+
-+        size_t field_len;  /* used for binary fields: the field name length */
-+        size_t data_size;  /* and the size of the binary data chunk being processed */
- 
-         struct iovec_wrapper iovw;
- 
-diff --git a/src/journal/journal-authenticate.c b/src/journal/journal-authenticate.c
-index 5ab1982..1f980ee 100644
---- a/src/journal/journal-authenticate.c
-+++ b/src/journal/journal-authenticate.c
-@@ -229,7 +229,7 @@ int journal_file_maybe_append_tag(JournalFile *f, uint64_t realtime) {
-         return 0;
- }
- 
--int journal_file_hmac_put_object(JournalFile *f, int type, Object *o, uint64_t p) {
-+int journal_file_hmac_put_object(JournalFile *f, ObjectType type, Object *o, uint64_t p) {
-         int r;
- 
-         assert(f);
-@@ -246,7 +246,7 @@ int journal_file_hmac_put_object(JournalFile *f, int type, Object *o, uint64_t p
-                 if (r < 0)
-                         return r;
-         } else {
--                if (type >= 0 && o->object.type != type)
-+                if (type > OBJECT_UNUSED && o->object.type != type)
-                         return -EBADMSG;
-         }
- 
-diff --git a/src/journal/journal-authenticate.h b/src/journal/journal-authenticate.h
-index 0aaf836..565fe84 100644
---- a/src/journal/journal-authenticate.h
-+++ b/src/journal/journal-authenticate.h
-@@ -33,7 +33,7 @@ int journal_file_append_first_tag(JournalFile *f);
- int journal_file_hmac_setup(JournalFile *f);
- int journal_file_hmac_start(JournalFile *f);
- int journal_file_hmac_put_header(JournalFile *f);
--int journal_file_hmac_put_object(JournalFile *f, int type, Object *o, uint64_t p);
-+int journal_file_hmac_put_object(JournalFile *f, ObjectType type, Object *o, uint64_t p);
- 
- int journal_file_fss_load(JournalFile *f);
- int journal_file_parse_verification_key(JournalFile *f, const char *key);
-diff --git a/src/journal/journal-def.h b/src/journal/journal-def.h
-index e55fa19..ab089cb 100644
---- a/src/journal/journal-def.h
-+++ b/src/journal/journal-def.h
-@@ -52,8 +52,8 @@ typedef struct HashItem HashItem;
- typedef struct FSSHeader FSSHeader;
- 
- /* Object types */
--enum {
--        OBJECT_UNUSED,
-+typedef enum ObjectType {
-+        OBJECT_UNUSED, /* also serves as "any type" or "additional context" */
-         OBJECT_DATA,
-         OBJECT_FIELD,
-         OBJECT_ENTRY,
-@@ -62,7 +62,7 @@ enum {
-         OBJECT_ENTRY_ARRAY,
-         OBJECT_TAG,
-         _OBJECT_TYPE_MAX
--};
-+} ObjectType;
- 
- /* Object flags */
- enum {
-diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
-index 8a2c0fc..c55a4dc 100644
---- a/src/journal/journal-file.c
-+++ b/src/journal/journal-file.c
-@@ -374,7 +374,13 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
-         return 0;
- }
- 
--static int journal_file_move_to(JournalFile *f, int context, bool keep_always, uint64_t offset, uint64_t size, void **ret) {
-+static unsigned type_to_context(ObjectType type) {
-+        /* One context for each type, plus one catch-all for the rest */
-+        assert_cc(_OBJECT_TYPE_MAX <= MMAP_CACHE_MAX_CONTEXTS);
-+        return type > OBJECT_UNUSED && type < _OBJECT_TYPE_MAX ? type : 0;
-+}
-+
-+static int journal_file_move_to(JournalFile *f, ObjectType type, bool keep_always, uint64_t offset, uint64_t size, void **ret) {
-         assert(f);
-         assert(ret);
- 
-@@ -391,7 +397,7 @@ static int journal_file_move_to(JournalFile *f, int context, bool keep_always, u
-                         return -EADDRNOTAVAIL;
-         }
- 
--        return mmap_cache_get(f->mmap, f->fd, f->prot, context, keep_always, offset, size, &f->last_stat, ret, NULL);
-+        return mmap_cache_get(f->mmap, f->fd, f->prot, type_to_context(type), keep_always, offset, size, &f->last_stat, ret);
- }
- 
- static uint64_t minimum_header_size(Object *o) {
-@@ -412,7 +418,7 @@ static uint64_t minimum_header_size(Object *o) {
-         return table[o->object.type];
- }
- 
--int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret) {
-+int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset, Object **ret) {
-         int r;
-         void *t;
-         Object *o;
-@@ -425,7 +431,7 @@ int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Objec
-         if (!VALID64(offset))
-                 return -EFAULT;
- 
--        r = journal_file_move_to(f, type_to_context(type), false, offset, sizeof(ObjectHeader), &t);
-+        r = journal_file_move_to(f, type, false, offset, sizeof(ObjectHeader), &t);
-         if (r < 0)
-                 return r;
- 
-@@ -441,11 +447,11 @@ int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Objec
-         if (s < minimum_header_size(o))
-                 return -EBADMSG;
- 
--        if (type > 0 && o->object.type != type)
-+        if (type > OBJECT_UNUSED && o->object.type != type)
-                 return -EBADMSG;
- 
-         if (s > sizeof(ObjectHeader)) {
--                r = journal_file_move_to(f, o->object.type, false, offset, s, &t);
-+                r = journal_file_move_to(f, type, false, offset, s, &t);
-                 if (r < 0)
-                         return r;
- 
-@@ -482,14 +488,14 @@ static uint64_t journal_file_entry_seqnum(JournalFile *f, uint64_t *seqnum) {
-         return r;
- }
- 
--int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object **ret, uint64_t *offset) {
-+int journal_file_append_object(JournalFile *f, ObjectType type, uint64_t size, Object **ret, uint64_t *offset) {
-         int r;
-         uint64_t p;
-         Object *tail, *o;
-         void *t;
- 
-         assert(f);
--        assert(type > 0 && type < _OBJECT_TYPE_MAX);
-+        assert(type > OBJECT_UNUSED && type < _OBJECT_TYPE_MAX);
-         assert(size >= sizeof(ObjectHeader));
-         assert(offset);
-         assert(ret);
-@@ -502,7 +508,7 @@ int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object *
-         if (p == 0)
-                 p = le64toh(f->header->header_size);
-         else {
--                r = journal_file_move_to_object(f, -1, p, &tail);
-+                r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &tail);
-                 if (r < 0)
-                         return r;
- 
-@@ -1657,7 +1663,7 @@ static int generic_array_bisect(
-                         }
-                 }
- 
--                if (k > n) {
-+                if (k >= n) {
-                         if (direction == DIRECTION_UP) {
-                                 i = n;
-                                 subtract_one = true;
-@@ -1793,23 +1799,6 @@ _pure_ static int test_object_offset(JournalFile *f, uint64_t p, uint64_t needle
-                 return TEST_RIGHT;
- }
- 
--int journal_file_move_to_entry_by_offset(
--                JournalFile *f,
--                uint64_t p,
--                direction_t direction,
--                Object **ret,
--                uint64_t *offset) {
--
--        return generic_array_bisect(f,
--                                    le64toh(f->header->entry_array_offset),
--                                    le64toh(f->header->n_entries),
--                                    p,
--                                    test_object_offset,
--                                    direction,
--                                    ret, offset, NULL);
--}
--
--
- static int test_object_seqnum(JournalFile *f, uint64_t p, uint64_t needle) {
-         Object *o;
-         int r;
-@@ -1939,9 +1928,81 @@ int journal_file_move_to_entry_by_monotonic(
-                                              ret, offset, NULL);
- }
- 
-+void journal_file_reset_location(JournalFile *f) {
-+        f->location_type = LOCATION_HEAD;
-+        f->current_offset = 0;
-+        f->current_seqnum = 0;
-+        f->current_realtime = 0;
-+        f->current_monotonic = 0;
-+        zero(f->current_boot_id);
-+        f->current_xor_hash = 0;
-+}
-+
-+void journal_file_save_location(JournalFile *f, Object *o, uint64_t offset) {
-+        f->location_type = LOCATION_SEEK;
-+        f->current_offset = offset;
-+        f->current_seqnum = le64toh(o->entry.seqnum);
-+        f->current_realtime = le64toh(o->entry.realtime);
-+        f->current_monotonic = le64toh(o->entry.monotonic);
-+        f->current_boot_id = o->entry.boot_id;
-+        f->current_xor_hash = le64toh(o->entry.xor_hash);
-+}
-+
-+int journal_file_compare_locations(JournalFile *af, JournalFile *bf) {
-+        assert(af);
-+        assert(bf);
-+        assert(af->location_type == LOCATION_SEEK);
-+        assert(bf->location_type == LOCATION_SEEK);
-+
-+        /* If contents and timestamps match, these entries are
-+         * identical, even if the seqnum does not match */
-+        if (sd_id128_equal(af->current_boot_id, bf->current_boot_id) &&
-+            af->current_monotonic == bf->current_monotonic &&
-+            af->current_realtime == bf->current_realtime &&
-+            af->current_xor_hash == bf->current_xor_hash)
-+                return 0;
-+
-+        if (sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id)) {
-+
-+                /* If this is from the same seqnum source, compare
-+                 * seqnums */
-+                if (af->current_seqnum < bf->current_seqnum)
-+                        return -1;
-+                if (af->current_seqnum > bf->current_seqnum)
-+                        return 1;
-+
-+                /* Wow! This is weird, different data but the same
-+                 * seqnums? Something is borked, but let's make the
-+                 * best of it and compare by time. */
-+        }
-+
-+        if (sd_id128_equal(af->current_boot_id, bf->current_boot_id)) {
-+
-+                /* If the boot id matches, compare monotonic time */
-+                if (af->current_monotonic < bf->current_monotonic)
-+                        return -1;
-+                if (af->current_monotonic > bf->current_monotonic)
-+                        return 1;
-+        }
-+
-+        /* Otherwise, compare UTC time */
-+        if (af->current_realtime < bf->current_realtime)
-+                return -1;
-+        if (af->current_realtime > bf->current_realtime)
-+                return 1;
-+
-+        /* Finally, compare by contents */
-+        if (af->current_xor_hash < bf->current_xor_hash)
-+                return -1;
-+        if (af->current_xor_hash > bf->current_xor_hash)
-+                return 1;
-+
-+        return 0;
-+}
-+
- int journal_file_next_entry(
-                 JournalFile *f,
--                Object *o, uint64_t p,
-+                uint64_t p,
-                 direction_t direction,
-                 Object **ret, uint64_t *offset) {
- 
-@@ -1949,18 +2010,14 @@ int journal_file_next_entry(
-         int r;
- 
-         assert(f);
--        assert(p > 0 || !o);
- 
-         n = le64toh(f->header->n_entries);
-         if (n <= 0)
-                 return 0;
- 
--        if (!o)
-+        if (p == 0)
-                 i = direction == DIRECTION_DOWN ? 0 : n - 1;
-         else {
--                if (o->object.type != OBJECT_ENTRY)
--                        return -EINVAL;
--
-                 r = generic_array_bisect(f,
-                                          le64toh(f->header->entry_array_offset),
-                                          le64toh(f->header->n_entries),
-@@ -2006,55 +2063,6 @@ int journal_file_next_entry(
-         return 1;
- }
- 
--int journal_file_skip_entry(
--                JournalFile *f,
--                Object *o, uint64_t p,
--                int64_t skip,
--                Object **ret, uint64_t *offset) {
--
--        uint64_t i, n;
--        int r;
--
--        assert(f);
--        assert(o);
--        assert(p > 0);
--
--        if (o->object.type != OBJECT_ENTRY)
--                return -EINVAL;
--
--        r = generic_array_bisect(f,
--                                 le64toh(f->header->entry_array_offset),
--                                 le64toh(f->header->n_entries),
--                                 p,
--                                 test_object_offset,
--                                 DIRECTION_DOWN,
--                                 NULL, NULL,
--                                 &i);
--        if (r <= 0)
--                return r;
--
--        /* Calculate new index */
--        if (skip < 0) {
--                if ((uint64_t) -skip >= i)
--                        i = 0;
--                else
--                        i = i - (uint64_t) -skip;
--        } else
--                i  += (uint64_t) skip;
--
--        n = le64toh(f->header->n_entries);
--        if (n <= 0)
--                return -EBADMSG;
--
--        if (i >= n)
--                i = n-1;
--
--        return generic_array_get(f,
--                                 le64toh(f->header->entry_array_offset),
--                                 i,
--                                 ret, offset);
--}
--
- int journal_file_next_entry_for_data(
-                 JournalFile *f,
-                 Object *o, uint64_t p,
-@@ -2289,7 +2297,7 @@ void journal_file_dump(JournalFile *f) {
- 
-         p = le64toh(f->header->header_size);
-         while (p != 0) {
--                r = journal_file_move_to_object(f, -1, p, &o);
-+                r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &o);
-                 if (r < 0)
-                         goto fail;
- 
-diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
-index 211e121..ca17c97 100644
---- a/src/journal/journal-file.h
-+++ b/src/journal/journal-file.h
-@@ -48,6 +48,20 @@ typedef enum direction {
-         DIRECTION_DOWN
- } direction_t;
- 
-+typedef enum LocationType {
-+        /* The first and last entries, resp. */
-+        LOCATION_HEAD,
-+        LOCATION_TAIL,
-+
-+        /* We already read the entry we currently point to, and the
-+         * next one to read should probably not be this one again. */
-+        LOCATION_DISCRETE,
-+
-+        /* We should seek to the precise location specified, and
-+         * return it, as we haven't read it yet. */
-+        LOCATION_SEEK
-+} LocationType;
-+
- typedef struct JournalFile {
-         int fd;
- 
-@@ -63,6 +77,8 @@ typedef struct JournalFile {
-         bool tail_entry_monotonic_valid:1;
- 
-         direction_t last_direction;
-+        LocationType location_type;
-+        uint64_t last_n_entries;
- 
-         char *path;
-         struct stat last_stat;
-@@ -72,6 +88,11 @@ typedef struct JournalFile {
-         HashItem *field_hash_table;
- 
-         uint64_t current_offset;
-+        uint64_t current_seqnum;
-+        uint64_t current_realtime;
-+        uint64_t current_monotonic;
-+        sd_id128_t current_boot_id;
-+        uint64_t current_xor_hash;
- 
-         JournalMetrics metrics;
-         MMapCache *mmap;
-@@ -160,13 +181,13 @@ static inline bool VALID_EPOCH(uint64_t u) {
- #define JOURNAL_HEADER_COMPRESSED_LZ4(h) \
-         (!!(le32toh((h)->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED_LZ4))
- 
--int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret);
-+int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset, Object **ret);
- 
- uint64_t journal_file_entry_n_items(Object *o) _pure_;
- uint64_t journal_file_entry_array_n_items(Object *o) _pure_;
- uint64_t journal_file_hash_table_n_items(Object *o) _pure_;
- 
--int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object **ret, uint64_t *offset);
-+int journal_file_append_object(JournalFile *f, ObjectType type, uint64_t size, Object **ret, uint64_t *offset);
- int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqno, Object **ret, uint64_t *offset);
- 
- int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset);
-@@ -175,12 +196,13 @@ int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, ui
- int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t size, Object **ret, uint64_t *offset);
- int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset);
- 
--int journal_file_next_entry(JournalFile *f, Object *o, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
--int journal_file_skip_entry(JournalFile *f, Object *o, uint64_t p, int64_t skip, Object **ret, uint64_t *offset);
-+void journal_file_reset_location(JournalFile *f);
-+void journal_file_save_location(JournalFile *f, Object *o, uint64_t offset);
-+int journal_file_compare_locations(JournalFile *af, JournalFile *bf);
-+int journal_file_next_entry(JournalFile *f, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
- 
- int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset);
- 
--int journal_file_move_to_entry_by_offset(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
- int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
- int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset);
- int journal_file_move_to_entry_by_monotonic(JournalFile *f, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset);
-@@ -205,21 +227,3 @@ int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *
- int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot, usec_t *from, usec_t *to);
- 
- bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec);
--
--
--static unsigned type_to_context(int type) {
--        /* One context for each type, plus one catch-all for the rest */
--        return type > 0 && type < _OBJECT_TYPE_MAX ? type : 0;
--}
--
--static inline int journal_file_object_keep(JournalFile *f, Object *o, uint64_t offset, void **release_cookie) {
--        unsigned context = type_to_context(o->object.type);
--        uint64_t s = le64toh(o->object.size);
--
--        return mmap_cache_get(f->mmap, f->fd, f->prot, context, true,
--                              offset, s, &f->last_stat, NULL, release_cookie);
--}
--
--static inline int journal_file_object_release(JournalFile *f, void *release_cookie) {
--        return mmap_cache_release(f->mmap, f->fd, release_cookie);
--}
-diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h
-index 70847db..e99050c 100644
---- a/src/journal/journal-internal.h
-+++ b/src/journal/journal-internal.h
-@@ -57,20 +57,6 @@ struct Match {
-         LIST_HEAD(Match, matches);
- };
- 
--typedef enum LocationType {
--        /* The first and last entries, resp. */
--        LOCATION_HEAD,
--        LOCATION_TAIL,
--
--        /* We already read the entry we currently point to, and the
--         * next one to read should probably not be this one again. */
--        LOCATION_DISCRETE,
--
--        /* We should seek to the precise location specified, and
--         * return it, as we haven't read it yet. */
--        LOCATION_SEEK
--} LocationType;
--
- struct Location {
-         LocationType type;
- 
-diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
-index f74adcb..5baa22d 100644
---- a/src/journal/journal-verify.c
-+++ b/src/journal/journal-verify.c
-@@ -368,7 +368,7 @@ static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
- 
-                 c = (a + b) / 2;
- 
--                r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z, NULL);
-+                r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z);
-                 if (r < 0)
-                         return r;
- 
-@@ -865,7 +865,7 @@ int journal_file_verify(
-                 if (show_progress)
-                         draw_progress(0x7FFF * p / le64toh(f->header->tail_object_offset), &last_usec);
- 
--                r = journal_file_move_to_object(f, -1, p, &o);
-+                r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &o);
-                 if (r < 0) {
-                         error(p, "invalid object");
-                         goto fail;
-@@ -1085,11 +1085,11 @@ int journal_file_verify(
-                                         q = last_tag;
- 
-                                 while (q <= p) {
--                                        r = journal_file_move_to_object(f, -1, q, &o);
-+                                        r = journal_file_move_to_object(f, OBJECT_UNUSED, q, &o);
-                                         if (r < 0)
-                                                 goto fail;
- 
--                                        r = journal_file_hmac_put_object(f, -1, o, q);
-+                                        r = journal_file_hmac_put_object(f, OBJECT_UNUSED, o, q);
-                                         if (r < 0)
-                                                 goto fail;
- 
-@@ -1097,7 +1097,7 @@ int journal_file_verify(
-                                 }
- 
-                                 /* Position might have changed, let's reposition things */
--                                r = journal_file_move_to_object(f, -1, p, &o);
-+                                r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &o);
-                                 if (r < 0)
-                                         goto fail;
- 
-diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
-index f50faf4..03579fd 100644
---- a/src/journal/journalctl.c
-+++ b/src/journal/journalctl.c
-@@ -682,7 +682,7 @@ static int parse_argv(int argc, char *argv[]) {
-                         assert_not_reached("Unhandled option");
-                 }
- 
--        if (arg_follow && !arg_no_tail && arg_lines == ARG_LINES_DEFAULT)
-+        if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT)
-                 arg_lines = 10;
- 
-         if (!!arg_directory + !!arg_file + !!arg_machine > 1) {
-diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c
-index a635202..655e2dd 100644
---- a/src/journal/journald-native.c
-+++ b/src/journal/journald-native.c
-@@ -132,8 +132,8 @@ void server_process_native_message(
- 
-                 /* A property follows */
- 
--                /* n received properties, +1 for _TRANSPORT */
--                if (!GREEDY_REALLOC(iovec, m, n + 1 + N_IOVEC_META_FIELDS + !!object_pid * N_IOVEC_OBJECT_FIELDS)) {
-+                /* n existing properties, 1 new, +1 for _TRANSPORT */
-+                if (!GREEDY_REALLOC(iovec, m, n + 2 + N_IOVEC_META_FIELDS + N_IOVEC_OBJECT_FIELDS)) {
-                         log_oom();
-                         break;
-                 }
-diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
-index 12735c4..08b143b 100644
---- a/src/journal/journald-server.c
-+++ b/src/journal/journald-server.c
-@@ -1655,6 +1655,7 @@ void server_done(Server *s) {
-         free(s->buffer);
-         free(s->tty_path);
-         free(s->cgroup_root);
-+        free(s->hostname_field);
- 
-         if (s->mmap)
-                 mmap_cache_unref(s->mmap);
-diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c
-index b7db6f1..f6f669d 100644
---- a/src/journal/mmap-cache.c
-+++ b/src/journal/mmap-cache.c
-@@ -38,7 +38,7 @@ typedef struct FileDescriptor FileDescriptor;
- struct Window {
-         MMapCache *cache;
- 
--        unsigned keep_always;
-+        bool keep_always;
-         bool in_unused;
- 
-         int prot;
-@@ -76,7 +76,7 @@ struct MMapCache {
- 
- 
-         Hashmap *fds;
--        Hashmap *contexts;
-+        Context *contexts[MMAP_CACHE_MAX_CONTEXTS];
- 
-         LIST_HEAD(Window, unused);
-         Window *last_unused;
-@@ -185,7 +185,7 @@ static void context_detach_window(Context *c) {
-         c->window = NULL;
-         LIST_REMOVE(by_window, w->contexts, c);
- 
--        if (!w->contexts && w->keep_always == 0) {
-+        if (!w->contexts && !w->keep_always) {
-                 /* Not used anymore? */
-                 LIST_PREPEND(unused, c->cache->unused, w);
-                 if (!c->cache->last_unused)
-@@ -219,18 +219,13 @@ static void context_attach_window(Context *c, Window *w) {
- 
- static Context *context_add(MMapCache *m, unsigned id) {
-         Context *c;
--        int r;
- 
-         assert(m);
- 
--        c = hashmap_get(m->contexts, UINT_TO_PTR(id + 1));
-+        c = m->contexts[id];
-         if (c)
-                 return c;
- 
--        r = hashmap_ensure_allocated(&m->contexts, NULL);
--        if (r < 0)
--                return NULL;
--
-         c = new0(Context, 1);
-         if (!c)
-                 return NULL;
-@@ -238,11 +233,8 @@ static Context *context_add(MMapCache *m, unsigned id) {
-         c->cache = m;
-         c->id = id;
- 
--        r = hashmap_put(m->contexts, UINT_TO_PTR(id + 1), c);
--        if (r < 0) {
--                free(c);
--                return NULL;
--        }
-+        assert(!m->contexts[id]);
-+        m->contexts[id] = c;
- 
-         return c;
- }
-@@ -252,8 +244,10 @@ static void context_free(Context *c) {
- 
-         context_detach_window(c);
- 
--        if (c->cache)
--                assert_se(hashmap_remove(c->cache->contexts, UINT_TO_PTR(c->id + 1)));
-+        if (c->cache) {
-+                assert(c->cache->contexts[c->id] == c);
-+                c->cache->contexts[c->id] = NULL;
-+        }
- 
-         free(c);
- }
-@@ -302,15 +296,14 @@ static FileDescriptor* fd_add(MMapCache *m, int fd) {
- }
- 
- static void mmap_cache_free(MMapCache *m) {
--        Context *c;
-         FileDescriptor *f;
-+        int i;
- 
-         assert(m);
- 
--        while ((c = hashmap_first(m->contexts)))
--                context_free(c);
--
--        hashmap_free(m->contexts);
-+        for (i = 0; i < MMAP_CACHE_MAX_CONTEXTS; i++)
-+                if (m->contexts[i])
-+                        context_free(m->contexts[i]);
- 
-         while ((f = hashmap_first(m->fds)))
-                 fd_free(f);
-@@ -352,8 +345,7 @@ static int try_context(
-                 bool keep_always,
-                 uint64_t offset,
-                 size_t size,
--                void **ret,
--                void **release_cookie) {
-+                void **ret) {
- 
-         Context *c;
- 
-@@ -361,8 +353,9 @@ static int try_context(
-         assert(m->n_ref > 0);
-         assert(fd >= 0);
-         assert(size > 0);
-+        assert(ret);
- 
--        c = hashmap_get(m->contexts, UINT_TO_PTR(context+1));
-+        c = m->contexts[context];
-         if (!c)
-                 return 0;
- 
-@@ -378,12 +371,9 @@ static int try_context(
-                 return 0;
-         }
- 
--        c->window->keep_always += keep_always;
-+        c->window->keep_always |= keep_always;
- 
--        if (ret)
--                *ret = (uint8_t*) c->window->ptr + (offset - c->window->offset);
--        if (keep_always && release_cookie)
--                *release_cookie = c->window;
-+        *ret = (uint8_t*) c->window->ptr + (offset - c->window->offset);
-         return 1;
- }
- 
-@@ -395,8 +385,7 @@ static int find_mmap(
-                 bool keep_always,
-                 uint64_t offset,
-                 size_t size,
--                void **ret,
--                void **release_cookie) {
-+                void **ret) {
- 
-         FileDescriptor *f;
-         Window *w;
-@@ -427,10 +416,7 @@ static int find_mmap(
-         context_attach_window(c, w);
-         w->keep_always += keep_always;
- 
--        if (ret)
--                *ret = (uint8_t*) w->ptr + (offset - w->offset);
--        if (keep_always && release_cookie)
--                *release_cookie = c->window;
-+        *ret = (uint8_t*) w->ptr + (offset - w->offset);
-         return 1;
- }
- 
-@@ -443,8 +429,7 @@ static int add_mmap(
-                 uint64_t offset,
-                 size_t size,
-                 struct stat *st,
--                void **ret,
--                void **release_cookie) {
-+                void **ret) {
- 
-         uint64_t woffset, wsize;
-         Context *c;
-@@ -457,6 +442,7 @@ static int add_mmap(
-         assert(m->n_ref > 0);
-         assert(fd >= 0);
-         assert(size > 0);
-+        assert(ret);
- 
-         woffset = offset & ~((uint64_t) page_size() - 1ULL);
-         wsize = size + (offset - woffset);
-@@ -526,10 +512,7 @@ static int add_mmap(
-         c->window = w;
-         LIST_PREPEND(by_window, w->contexts, c);
- 
--        if (ret)
--                *ret = (uint8_t*) w->ptr + (offset - w->offset);
--        if (keep_always && release_cookie)
--                *release_cookie = c->window;
-+        *ret = (uint8_t*) w->ptr + (offset - w->offset);
-         return 1;
- 
- outofmem:
-@@ -546,8 +529,7 @@ int mmap_cache_get(
-                 uint64_t offset,
-                 size_t size,
-                 struct stat *st,
--                void **ret,
--                void **release_cookie) {
-+                void **ret) {
- 
-         int r;
- 
-@@ -555,16 +537,18 @@ int mmap_cache_get(
-         assert(m->n_ref > 0);
-         assert(fd >= 0);
-         assert(size > 0);
-+        assert(ret);
-+        assert(context < MMAP_CACHE_MAX_CONTEXTS);
- 
-         /* Check whether the current context is the right one already */
--        r = try_context(m, fd, prot, context, keep_always, offset, size, ret, release_cookie);
-+        r = try_context(m, fd, prot, context, keep_always, offset, size, ret);
-         if (r != 0) {
-                 m->n_hit ++;
-                 return r;
-         }
- 
-         /* Search for a matching mmap */
--        r = find_mmap(m, fd, prot, context, keep_always, offset, size, ret, release_cookie);
-+        r = find_mmap(m, fd, prot, context, keep_always, offset, size, ret);
-         if (r != 0) {
-                 m->n_hit ++;
-                 return r;
-@@ -573,39 +557,7 @@ int mmap_cache_get(
-         m->n_missed++;
- 
-         /* Create a new mmap */
--        return add_mmap(m, fd, prot, context, keep_always, offset, size, st, ret, release_cookie);
--}
--
--int mmap_cache_release(
--                MMapCache *m,
--                int fd,
--                void *release_cookie) {
--
--        FileDescriptor *f;
--        Window *w;
--
--        assert(m);
--        assert(m->n_ref > 0);
--        assert(fd >= 0);
--
--        f = hashmap_get(m->fds, INT_TO_PTR(fd + 1));
--        if (!f)
--                return -EBADF;
--
--        assert(f->fd == fd);
--
--        LIST_FOREACH(by_fd, w, f->windows)
--                if (w == release_cookie)
--                        break;
--
--        if (!w)
--                return -ENOENT;
--
--        if (w->keep_always == 0)
--                return -ENOLCK;
--
--        w->keep_always -= 1;
--        return 0;
-+        return add_mmap(m, fd, prot, context, keep_always, offset, size, st, ret);
- }
- 
- void mmap_cache_close_fd(MMapCache *m, int fd) {
-@@ -621,18 +573,6 @@ void mmap_cache_close_fd(MMapCache *m, int fd) {
-         fd_free(f);
- }
- 
--void mmap_cache_close_context(MMapCache *m, unsigned context) {
--        Context *c;
--
--        assert(m);
--
--        c = hashmap_get(m->contexts, UINT_TO_PTR(context + 1));
--        if (!c)
--                return;
--
--        context_free(c);
--}
--
- unsigned mmap_cache_get_hit(MMapCache *m) {
-         assert(m);
- 
-diff --git a/src/journal/mmap-cache.h b/src/journal/mmap-cache.h
-index 76e5316..fe2c83d 100644
---- a/src/journal/mmap-cache.h
-+++ b/src/journal/mmap-cache.h
-@@ -25,6 +25,8 @@
- #include <stdbool.h>
- #include <sys/stat.h>
- 
-+#define MMAP_CACHE_MAX_CONTEXTS 8
-+
- typedef struct MMapCache MMapCache;
- 
- MMapCache* mmap_cache_new(void);
-@@ -40,14 +42,8 @@ int mmap_cache_get(
-         uint64_t offset,
-         size_t size,
-         struct stat *st,
--        void **ret,
--        void **release_cookie);
--int mmap_cache_release(
--        MMapCache *m,
--        int fd,
--        void *release_cookie);
-+        void **ret);
- void mmap_cache_close_fd(MMapCache *m, int fd);
--void mmap_cache_close_context(MMapCache *m, unsigned context);
- 
- unsigned mmap_cache_get_hit(MMapCache *m);
- unsigned mmap_cache_get_missed(MMapCache *m);
-diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
-index cf21c4d..cb7fc32 100644
---- a/src/journal/sd-journal.c
-+++ b/src/journal/sd-journal.c
-@@ -87,7 +87,7 @@ static void detach_location(sd_journal *j) {
-         j->current_field = 0;
- 
-         ORDERED_HASHMAP_FOREACH(f, j->files, i)
--                f->current_offset = 0;
-+                journal_file_reset_location(f);
- }
- 
- static void reset_location(sd_journal *j) {
-@@ -114,20 +114,19 @@ static void init_location(Location *l, LocationType type, JournalFile *f, Object
-         l->seqnum_set = l->realtime_set = l->monotonic_set = l->xor_hash_set = true;
- }
- 
--static void set_location(sd_journal *j, LocationType type, JournalFile *f, Object *o,
--                         direction_t direction, uint64_t offset) {
-+static void set_location(sd_journal *j, JournalFile *f, Object *o) {
-         assert(j);
--        assert(type == LOCATION_DISCRETE || type == LOCATION_SEEK);
-         assert(f);
-         assert(o);
- 
--        init_location(&j->current_location, type, f, o);
-+        init_location(&j->current_location, LOCATION_DISCRETE, f, o);
- 
-         j->current_file = f;
-         j->current_field = 0;
- 
--        f->last_direction = direction;
--        f->current_offset = offset;
-+        /* Let f know its candidate entry was picked. */
-+        assert(f->location_type == LOCATION_SEEK);
-+        f->location_type = LOCATION_DISCRETE;
- }
- 
- static int match_is_valid(const void *data, size_t size) {
-@@ -413,144 +412,51 @@ _public_ void sd_journal_flush_matches(sd_journal *j) {
-         detach_location(j);
- }
- 
--static int compare_entry_order(JournalFile *af, Object *_ao,
--                               JournalFile *bf, uint64_t bp) {
--
--        uint64_t a, b;
--        Object *ao, *bo;
--        int r;
--
--        assert(af);
--        assert(bf);
--        assert(_ao);
--
--        /* The mmap cache might invalidate the object from the first
--         * file if we look at the one from the second file. Hence
--         * temporarily copy the header of the first one, and look at
--         * that only. */
--        ao = alloca(offsetof(EntryObject, items));
--        memcpy(ao, _ao, offsetof(EntryObject, items));
--
--        r = journal_file_move_to_object(bf, OBJECT_ENTRY, bp, &bo);
--        if (r < 0)
--                return strcmp(af->path, bf->path);
--
--        /* We operate on two different files here, hence we can access
--         * two objects at the same time, which we normally can't.
--         *
--         * If contents and timestamps match, these entries are
--         * identical, even if the seqnum does not match */
--
--        if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id) &&
--            ao->entry.monotonic == bo->entry.monotonic &&
--            ao->entry.realtime == bo->entry.realtime &&
--            ao->entry.xor_hash == bo->entry.xor_hash)
--                return 0;
--
--        if (sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id)) {
--
--                /* If this is from the same seqnum source, compare
--                 * seqnums */
--                a = le64toh(ao->entry.seqnum);
--                b = le64toh(bo->entry.seqnum);
--
--                if (a < b)
--                        return -1;
--                if (a > b)
--                        return 1;
--
--                /* Wow! This is weird, different data but the same
--                 * seqnums? Something is borked, but let's make the
--                 * best of it and compare by time. */
--        }
--
--        if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id)) {
--
--                /* If the boot id matches, compare monotonic time */
--                a = le64toh(ao->entry.monotonic);
--                b = le64toh(bo->entry.monotonic);
--
--                if (a < b)
--                        return -1;
--                if (a > b)
--                        return 1;
--        }
--
--        /* Otherwise, compare UTC time */
--        a = le64toh(ao->entry.realtime);
--        b = le64toh(bo->entry.realtime);
--
--        if (a < b)
--                return -1;
--        if (a > b)
--                return 1;
--
--        /* Finally, compare by contents */
--        a = le64toh(ao->entry.xor_hash);
--        b = le64toh(bo->entry.xor_hash);
--
--        if (a < b)
--                return -1;
--        if (a > b)
--                return 1;
--
--        return 0;
--}
--
--_pure_ static int compare_with_location(JournalFile *af, Object *ao, Location *l) {
--        uint64_t a;
--
--        assert(af);
--        assert(ao);
-+_pure_ static int compare_with_location(JournalFile *f, Location *l) {
-+        assert(f);
-         assert(l);
-+        assert(f->location_type == LOCATION_SEEK);
-         assert(l->type == LOCATION_DISCRETE || l->type == LOCATION_SEEK);
- 
-         if (l->monotonic_set &&
--            sd_id128_equal(ao->entry.boot_id, l->boot_id) &&
-+            sd_id128_equal(f->current_boot_id, l->boot_id) &&
-             l->realtime_set &&
--            le64toh(ao->entry.realtime) == l->realtime &&
-+            f->current_realtime == l->realtime &&
-             l->xor_hash_set &&
--            le64toh(ao->entry.xor_hash) == l->xor_hash)
-+            f->current_xor_hash == l->xor_hash)
-                 return 0;
- 
-         if (l->seqnum_set &&
--            sd_id128_equal(af->header->seqnum_id, l->seqnum_id)) {
--
--                a = le64toh(ao->entry.seqnum);
-+            sd_id128_equal(f->header->seqnum_id, l->seqnum_id)) {
- 
--                if (a < l->seqnum)
-+                if (f->current_seqnum < l->seqnum)
-                         return -1;
--                if (a > l->seqnum)
-+                if (f->current_seqnum > l->seqnum)
-                         return 1;
-         }
- 
-         if (l->monotonic_set &&
--            sd_id128_equal(ao->entry.boot_id, l->boot_id)) {
-+            sd_id128_equal(f->current_boot_id, l->boot_id)) {
- 
--                a = le64toh(ao->entry.monotonic);
--
--                if (a < l->monotonic)
-+                if (f->current_monotonic < l->monotonic)
-                         return -1;
--                if (a > l->monotonic)
-+                if (f->current_monotonic > l->monotonic)
-                         return 1;
-         }
- 
-         if (l->realtime_set) {
- 
--                a = le64toh(ao->entry.realtime);
--
--                if (a < l->realtime)
-+                if (f->current_realtime < l->realtime)
-                         return -1;
--                if (a > l->realtime)
-+                if (f->current_realtime > l->realtime)
-                         return 1;
-         }
- 
-         if (l->xor_hash_set) {
--                a = le64toh(ao->entry.xor_hash);
- 
--                if (a < l->xor_hash)
-+                if (f->current_xor_hash < l->xor_hash)
-                         return -1;
--                if (a > l->xor_hash)
-+                if (f->current_xor_hash > l->xor_hash)
-                         return 1;
-         }
- 
-@@ -766,9 +672,9 @@ static int find_location_with_matches(
-                 /* No matches is simple */
- 
-                 if (j->current_location.type == LOCATION_HEAD)
--                        return journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, ret, offset);
-+                        return journal_file_next_entry(f, 0, DIRECTION_DOWN, ret, offset);
-                 if (j->current_location.type == LOCATION_TAIL)
--                        return journal_file_next_entry(f, NULL, 0, DIRECTION_UP, ret, offset);
-+                        return journal_file_next_entry(f, 0, DIRECTION_UP, ret, offset);
-                 if (j->current_location.seqnum_set && sd_id128_equal(j->current_location.seqnum_id, f->header->seqnum_id))
-                         return journal_file_move_to_entry_by_seqnum(f, j->current_location.seqnum, direction, ret, offset);
-                 if (j->current_location.monotonic_set) {
-@@ -779,7 +685,7 @@ static int find_location_with_matches(
-                 if (j->current_location.realtime_set)
-                         return journal_file_move_to_entry_by_realtime(f, j->current_location.realtime, direction, ret, offset);
- 
--                return journal_file_next_entry(f, NULL, 0, direction, ret, offset);
-+                return journal_file_next_entry(f, 0, direction, ret, offset);
-         } else
-                 return find_location_for_match(j, j->level0, f, direction, ret, offset);
- }
-@@ -791,49 +697,61 @@ static int next_with_matches(
-                 Object **ret,
-                 uint64_t *offset) {
- 
--        Object *c;
--        uint64_t cp;
--
-         assert(j);
-         assert(f);
-         assert(ret);
-         assert(offset);
- 
--        c = *ret;
--        cp = *offset;
--
-         /* No matches is easy. We simple advance the file
-          * pointer by one. */
-         if (!j->level0)
--                return journal_file_next_entry(f, c, cp, direction, ret, offset);
-+                return journal_file_next_entry(f, f->current_offset, direction, ret, offset);
- 
-         /* If we have a match then we look for the next matching entry
-          * with an offset at least one step larger */
--        return next_for_match(j, j->level0, f, direction == DIRECTION_DOWN ? cp+1 : cp-1, direction, ret, offset);
-+        return next_for_match(j, j->level0, f,
-+                              direction == DIRECTION_DOWN ? f->current_offset + 1
-+                                                          : f->current_offset - 1,
-+                              direction, ret, offset);
- }
- 
--static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direction, Object **ret, uint64_t *offset) {
-+static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direction) {
-         Object *c;
--        uint64_t cp;
-+        uint64_t cp, n_entries;
-         int r;
- 
-         assert(j);
-         assert(f);
- 
--        if (f->last_direction == direction && f->current_offset > 0) {
--                cp = f->current_offset;
-+        n_entries = le64toh(f->header->n_entries);
- 
--                r = journal_file_move_to_object(f, OBJECT_ENTRY, cp, &c);
--                if (r < 0)
--                        return r;
-+        /* If we hit EOF before, we don't need to look into this file again
-+         * unless direction changed or new entries appeared. */
-+        if (f->last_direction == direction && f->location_type == LOCATION_TAIL &&
-+            n_entries == f->last_n_entries)
-+                return 0;
- 
--                r = next_with_matches(j, f, direction, &c, &cp);
--                if (r <= 0)
--                        return r;
-+        f->last_n_entries = n_entries;
-+
-+        if (f->last_direction == direction && f->current_offset > 0) {
-+                /* LOCATION_SEEK here means we did the work in a previous
-+                 * iteration and the current location already points to a
-+                 * candidate entry. */
-+                if (f->location_type != LOCATION_SEEK) {
-+                        r = next_with_matches(j, f, direction, &c, &cp);
-+                        if (r <= 0)
-+                                return r;
-+
-+                        journal_file_save_location(f, c, cp);
-+                }
-         } else {
-+                f->last_direction = direction;
-+
-                 r = find_location_with_matches(j, f, direction, &c, &cp);
-                 if (r <= 0)
-                         return r;
-+
-+                journal_file_save_location(f, c, cp);
-         }
- 
-         /* OK, we found the spot, now let's advance until an entry
-@@ -848,30 +766,25 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc
-                 if (j->current_location.type == LOCATION_DISCRETE) {
-                         int k;
- 
--                        k = compare_with_location(f, c, &j->current_location);
-+                        k = compare_with_location(f, &j->current_location);
- 
-                         found = direction == DIRECTION_DOWN ? k > 0 : k < 0;
-                 } else
-                         found = true;
- 
--                if (found) {
--                        if (ret)
--                                *ret = c;
--                        if (offset)
--                                *offset = cp;
-+                if (found)
-                         return 1;
--                }
- 
-                 r = next_with_matches(j, f, direction, &c, &cp);
-                 if (r <= 0)
-                         return r;
-+
-+                journal_file_save_location(f, c, cp);
-         }
- }
- 
- static int real_journal_next(sd_journal *j, direction_t direction) {
-         JournalFile *f, *new_file = NULL;
--        uint64_t new_offset = 0;
--        uint64_t p = 0;
-         Iterator i;
-         Object *o;
-         int r;
-@@ -882,38 +795,38 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
-         ORDERED_HASHMAP_FOREACH(f, j->files, i) {
-                 bool found;
- 
--                r = next_beyond_location(j, f, direction, &o, &p);
-+                r = next_beyond_location(j, f, direction);
-                 if (r < 0) {
-                         log_debug("Can't iterate through %s, ignoring: %s", f->path, strerror(-r));
-                         remove_file_real(j, f);
-                         continue;
--                } else if (r == 0)
-+                } else if (r == 0) {
-+                        f->location_type = LOCATION_TAIL;
-                         continue;
-+                }
- 
-                 if (!new_file)
-                         found = true;
-                 else {
-                         int k;
- 
--                        k = compare_entry_order(f, o, new_file, new_offset);
-+                        k = journal_file_compare_locations(f, new_file);
- 
-                         found = direction == DIRECTION_DOWN ? k < 0 : k > 0;
-                 }
- 
--                if (found) {
-+                if (found)
-                         new_file = f;
--                        new_offset = p;
--                }
-         }
- 
-         if (!new_file)
-                 return 0;
- 
--        r = journal_file_move_to_object(new_file, OBJECT_ENTRY, new_offset, &o);
-+        r = journal_file_move_to_object(new_file, OBJECT_ENTRY, new_file->current_offset, &o);
-         if (r < 0)
-                 return r;
- 
--        set_location(j, LOCATION_DISCRETE, new_file, o, direction, new_offset);
-+        set_location(j, new_file, o);
- 
-         return 1;
- }
-@@ -2526,7 +2439,6 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_
-                 size_t ol;
-                 bool found;
-                 int r;
--                void *release_cookie;
- 
-                 /* Proceed to next data object in the field's linked list */
-                 if (j->unique_offset == 0) {
-@@ -2552,10 +2464,10 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_
-                         continue;
-                 }
- 
--                /* We do not use the type context here, but 0 instead,
--                 * so that we can look at this data object at the same
-+                /* We do not use OBJECT_DATA context here, but OBJECT_UNUSED
-+                 * instead, so that we can look at this data object at the same
-                  * time as one on another file */
--                r = journal_file_move_to_object(j->unique_file, 0, j->unique_offset, &o);
-+                r = journal_file_move_to_object(j->unique_file, OBJECT_UNUSED, j->unique_offset, &o);
-                 if (r < 0)
-                         return r;
- 
-@@ -2567,10 +2479,6 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_
-                         return -EBADMSG;
-                 }
- 
--                r = journal_file_object_keep(j->unique_file, o, j->unique_offset, &release_cookie);
--                if (r < 0)
--                        return r;
--
-                 r = return_data(j, j->unique_file, o, &odata, &ol);
-                 if (r < 0)
-                         return r;
-@@ -2615,10 +2523,6 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_
-                                 found = true;
-                 }
- 
--                r = journal_file_object_release(j->unique_file, release_cookie);
--                if (r < 0)
--                        return r;
--
-                 if (found)
-                         continue;
- 
-diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
-index 372f3ed..d56ee51 100644
---- a/src/libsystemd-network/network-internal.c
-+++ b/src/libsystemd-network/network-internal.c
-@@ -392,10 +392,12 @@ void serialize_dhcp_routes(FILE *f, const char *key, struct sd_dhcp_route *route
- 
-         fprintf(f, "%s=", key);
- 
--        for (i = 0; i < size; i++)
--                fprintf(f, "%s/%" PRIu8 ",%s%s", inet_ntoa(routes[i].dst_addr),
--                        routes[i].dst_prefixlen, inet_ntoa(routes[i].gw_addr),
-+        for (i = 0; i < size; i++) {
-+                fprintf(f, "%s/%" PRIu8, inet_ntoa(routes[i].dst_addr),
-+                        routes[i].dst_prefixlen);
-+                fprintf(f, ",%s%s", inet_ntoa(routes[i].gw_addr),
-                         (i < (size - 1)) ? " ": "");
-+        }
- 
-         fputs("\n", f);
- }
-diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
-index 0eba4c3..9986b52 100644
---- a/src/libsystemd-network/sd-dhcp-client.c
-+++ b/src/libsystemd-network/sd-dhcp-client.c
-@@ -68,7 +68,6 @@ struct sd_dhcp_client {
-         uint32_t mtu;
-         uint32_t xid;
-         usec_t start_time;
--        uint16_t secs;
-         unsigned int attempt;
-         usec_t request_sent;
-         sd_event_source *timeout_t1;
-@@ -321,10 +320,12 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
-         _cleanup_free_ DHCPPacket *packet;
-         size_t optlen, optoffset, size;
-         be16_t max_size;
-+        usec_t time_now;
-+        uint16_t secs;
-         int r;
- 
-         assert(client);
--        assert(client->secs);
-+        assert(client->start_time);
-         assert(ret);
-         assert(_optlen);
-         assert(_optoffset);
-@@ -344,7 +345,15 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
- 
-         /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
-            refuse to issue an DHCP lease if 'secs' is set to zero */
--        packet->dhcp.secs = htobe16(client->secs);
-+        r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
-+        if (r < 0)
-+                return r;
-+        assert(time_now >= client->start_time);
-+
-+        /* seconds between sending first and last DISCOVER
-+         * must always be strictly positive to deal with broken servers */
-+        secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
-+        packet->dhcp.secs = htobe16(secs);
- 
-         /* RFC2132 section 4.1
-            A client that cannot receive unicast IP datagrams until its protocol
-@@ -441,24 +450,12 @@ static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet,
- static int client_send_discover(sd_dhcp_client *client) {
-         _cleanup_free_ DHCPPacket *discover = NULL;
-         size_t optoffset, optlen;
--        usec_t time_now;
-         int r;
- 
-         assert(client);
-         assert(client->state == DHCP_STATE_INIT ||
-                client->state == DHCP_STATE_SELECTING);
- 
--        /* See RFC2131 section 4.4.1 */
--
--        r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
--        if (r < 0)
--                return r;
--        assert(time_now >= client->start_time);
--
--        /* seconds between sending first and last DISCOVER
--         * must always be strictly positive to deal with broken servers */
--        client->secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
--
-         r = client_message_init(client, &discover, DHCP_DISCOVER,
-                                 &optlen, &optoffset);
-         if (r < 0)
-@@ -875,10 +872,8 @@ static int client_start(sd_dhcp_client *client) {
-         }
-         client->fd = r;
- 
--        if (client->state == DHCP_STATE_INIT) {
-+        if (client->state == DHCP_STATE_INIT || client->state == DHCP_STATE_INIT_REBOOT)
-                 client->start_time = now(clock_boottime_or_monotonic());
--                client->secs = 0;
--        }
- 
-         return client_initialize_events(client, client_receive_message_raw);
- }
-@@ -1269,6 +1264,9 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
-                 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))
-diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c
-index 4fb01c0..b7c9a07 100644
---- a/src/libsystemd-network/sd-dhcp-lease.c
-+++ b/src/libsystemd-network/sd-dhcp-lease.c
-@@ -50,7 +50,7 @@ int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) {
- 
- int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime) {
-         assert_return(lease, -EINVAL);
--        assert_return(lease, -EINVAL);
-+        assert_return(lifetime, -EINVAL);
- 
-         *lifetime = lease->lifetime;
- 
-diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
-index fa4f9b5..dbec1a2 100644
---- a/src/libsystemd-network/sd-dhcp6-client.c
-+++ b/src/libsystemd-network/sd-dhcp6-client.c
-@@ -200,19 +200,19 @@ int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *du
- 
-         switch (type) {
-         case DHCP6_DUID_LLT:
--                if (duid_len <= sizeof(client->duid.llt))
-+                if (duid_len <= sizeof(client->duid.llt) - 2)
-                         return -EINVAL;
-                 break;
-         case DHCP6_DUID_EN:
--                if (duid_len != sizeof(client->duid.en))
-+                if (duid_len != sizeof(client->duid.en) - 2)
-                         return -EINVAL;
-                 break;
-         case DHCP6_DUID_LL:
--                if (duid_len <= sizeof(client->duid.ll))
-+                if (duid_len <= sizeof(client->duid.ll) - 2)
-                         return -EINVAL;
-                 break;
-         case DHCP6_DUID_UUID:
--                if (duid_len != sizeof(client->duid.uuid))
-+                if (duid_len != sizeof(client->duid.uuid) - 2)
-                         return -EINVAL;
-                 break;
-         default:
-@@ -222,7 +222,7 @@ int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *du
- 
-         client->duid.raw.type = htobe16(type);
-         memcpy(&client->duid.raw.data, duid, duid_len);
--        client->duid_len = duid_len;
-+        client->duid_len = duid_len + 2;  /* +2 for sizeof(type) */
- 
-         return 0;
- }
-diff --git a/src/libsystemd/sd-bus/bus-match.c b/src/libsystemd/sd-bus/bus-match.c
-index 18afe0f..5658c61 100644
---- a/src/libsystemd/sd-bus/bus-match.c
-+++ b/src/libsystemd/sd-bus/bus-match.c
-@@ -537,7 +537,7 @@ static int bus_match_find_compare_value(
-         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 --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c
-index 0ab1119..6c3230a 100644
---- a/src/libsystemd/sd-bus/bus-objects.c
-+++ b/src/libsystemd/sd-bus/bus-objects.c
-@@ -617,6 +617,9 @@ static int property_get_set_callbacks_run(
-                         return r;
- 
-         } else {
-+                const char *signature = NULL;
-+                char type = 0;
-+
-                 if (c->vtable->type != _SD_BUS_VTABLE_WRITABLE_PROPERTY)
-                         return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Property '%s' is not writable.", c->member);
- 
-@@ -628,6 +631,13 @@ static int property_get_set_callbacks_run(
- 
-                 c->last_iteration = bus->iteration_counter;
- 
-+                r = sd_bus_message_peek_type(m, &type, &signature);
-+                if (r < 0)
-+                        return r;
-+
-+                if (type != 'v' || !streq(strempty(signature), strempty(c->vtable->x.property.signature)))
-+                        return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INVALID_ARGS, "Incorrect parameters for property '%s', expected '%s', got '%s'.", c->member, strempty(c->vtable->x.property.signature), strempty(signature));
-+
-                 r = sd_bus_message_enter_container(m, 'v', c->vtable->x.property.signature);
-                 if (r < 0)
-                         return r;
-diff --git a/src/libsystemd/sd-rtnl/rtnl-message.c b/src/libsystemd/sd-rtnl/rtnl-message.c
-index b501a52..740133a 100644
---- a/src/libsystemd/sd-rtnl/rtnl-message.c
-+++ b/src/libsystemd/sd-rtnl/rtnl-message.c
-@@ -36,6 +36,8 @@
- #define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->container_offsets[i]) : NULL)
- #define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
- 
-+#define RTA_TYPE(rta) ((rta)->rta_type & NLA_TYPE_MASK)
-+
- static int message_new_empty(sd_rtnl *rtnl, sd_rtnl_message **ret) {
-         sd_rtnl_message *m;
- 
-@@ -566,8 +568,8 @@ int sd_rtnl_message_append_string(sd_rtnl_message *m, unsigned short type, const
-                 size = (size_t)r;
- 
-         if (size) {
--                length = strnlen(data, size);
--                if (length >= size)
-+                length = strnlen(data, size+1);
-+                if (length > size)
-                         return -EINVAL;
-         } else
-                 length = strlen(data);
-@@ -1066,7 +1068,7 @@ int rtnl_message_parse(sd_rtnl_message *m,
-         *rta_tb_size = max + 1;
- 
-         for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
--                type = rta->rta_type;
-+                type = RTA_TYPE(rta);
- 
-                 /* if the kernel is newer than the headers we used
-                    when building, we ignore out-of-range attributes
-@@ -1222,7 +1224,7 @@ int socket_read_message(sd_rtnl *rtnl) {
-                 }
-         }
- 
--        for (new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len); new_msg = NLMSG_NEXT(new_msg, len)) {
-+        for (new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len) && !done; new_msg = NLMSG_NEXT(new_msg, len)) {
-                 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
-                 const NLType *nl_type;
- 
-@@ -1237,7 +1239,8 @@ int socket_read_message(sd_rtnl *rtnl) {
-                 if (new_msg->nlmsg_type == NLMSG_DONE) {
-                         /* finished reading multi-part message */
-                         done = true;
--                        break;
-+
-+                        continue;
-                 }
- 
-                 /* check that we support this message type */
-diff --git a/src/libudev/libudev-device.c b/src/libudev/libudev-device.c
-index 2699374..e2afcb8 100644
---- a/src/libudev/libudev-device.c
-+++ b/src/libudev/libudev-device.c
-@@ -730,8 +730,13 @@ _public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, con
-                         return NULL;
-         } else {
-                 /* everything else just needs to be a directory */
--                if (stat(path, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode))
-+                if (stat(path, &statbuf) != 0)
-                         return NULL;
-+
-+                if (!S_ISDIR(statbuf.st_mode)) {
-+                        errno = EISDIR;
-+                        return NULL;
-+                }
-         }
- 
-         udev_device = udev_device_new(udev);
-diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
-index b6d9bc6..759794f 100644
---- a/src/nspawn/nspawn.c
-+++ b/src/nspawn/nspawn.c
-@@ -758,7 +758,7 @@ static int mount_binds(const char *dest, char **l, bool ro) {
-                  * 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;
-@@ -818,7 +818,7 @@ static int mount_tmpfs(const char *dest) {
-                         return log_oom();
- 
-                 r = mkdir_label(where, 0755);
--                if (r < 0) {
-+                if (r < 0 && errno != EEXIST) {
-                         log_error("creating mount point for tmpfs %s failed: %s", where, strerror(-r));
- 
-                         return r;
-@@ -3073,6 +3073,7 @@ int main(int argc, char *argv[]) {
-                                 goto finish;
-                         }
-                 } else {
-+#if 0
-                         const char *p;
- 
-                         p = strappenda(arg_directory,
-@@ -3082,6 +3083,7 @@ int main(int argc, char *argv[]) {
-                                 goto finish;
- 
-                         }
-+#endif
-                 }
-         } else {
-                 char template[] = "/tmp/nspawn-root-XXXXXX";
-diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
-index 7375f77..ec8efcc 100644
---- a/src/resolve/resolved-dns-packet.c
-+++ b/src/resolve/resolved-dns-packet.c
-@@ -866,7 +866,7 @@ fail:
- 
- int dns_packet_read_name(DnsPacket *p, char **_ret,
-                          bool allow_compression, size_t *start) {
--        size_t saved_rindex, after_rindex = 0;
-+        size_t saved_rindex, after_rindex = 0, jump_barrier;
-         _cleanup_free_ char *ret = NULL;
-         size_t n = 0, allocated = 0;
-         bool first = true;
-@@ -876,6 +876,7 @@ int dns_packet_read_name(DnsPacket *p, char **_ret,
-         assert(_ret);
- 
-         saved_rindex = p->rindex;
-+        jump_barrier = p->rindex;
- 
-         for (;;) {
-                 uint8_t c, d;
-@@ -922,7 +923,7 @@ int dns_packet_read_name(DnsPacket *p, char **_ret,
-                                 goto fail;
- 
-                         ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
--                        if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= saved_rindex) {
-+                        if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier) {
-                                 r = -EBADMSG;
-                                 goto fail;
-                         }
-@@ -930,9 +931,13 @@ int dns_packet_read_name(DnsPacket *p, char **_ret,
-                         if (after_rindex == 0)
-                                 after_rindex = p->rindex;
- 
-+                        /* Jumps are limited to a "prior occurence" (RFC-1035 4.1.4) */
-+                        jump_barrier = ptr;
-                         p->rindex = ptr;
--                } else
-+                } else {
-+                        r = -EBADMSG;
-                         goto fail;
-+                }
-         }
- 
-         if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
-diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
-index 7d258c9..6dd4cad 100644
---- a/src/resolve/resolved.c
-+++ b/src/resolve/resolved.c
-@@ -108,7 +108,7 @@ int main(int argc, char *argv[]) {
- 
- finish:
-         sd_notify(false,
--                  "STOPPIN=1\n"
-+                  "STOPPING=1\n"
-                   "STATUS=Shutting down...");
- 
-         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
-diff --git a/src/run/run.c b/src/run/run.c
-index e3b6293..dcefb5c 100644
---- a/src/run/run.c
-+++ b/src/run/run.c
-@@ -573,9 +573,12 @@ int main(int argc, char* argv[]) {
-         if (r <= 0)
-                 goto finish;
- 
--        r = find_binary(argv[optind], &command);
-+        r = find_binary(argv[optind], arg_transport == BUS_TRANSPORT_LOCAL, &command);
-         if (r < 0) {
--                log_error("Failed to find executable %s: %s", argv[optind], strerror(-r));
-+                log_error("Failed to find executable %s%s: %s",
-+                          argv[optind],
-+                          arg_transport == BUS_TRANSPORT_LOCAL ? "" : " on local system",
-+                          strerror(-r));
-                 goto finish;
-         }
-         argv[optind] = command;
-diff --git a/src/shared/install.c b/src/shared/install.c
-index 035b44c..cab93e8 100644
---- a/src/shared/install.c
-+++ b/src/shared/install.c
-@@ -1620,12 +1620,10 @@ int unit_file_enable(
-         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;
-diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c
-index 8f75a8e..c800e01 100644
---- a/src/shared/path-lookup.c
-+++ b/src/shared/path-lookup.c
-@@ -86,17 +86,14 @@ static char** user_dirs(
-         const char * const config_unit_paths[] = {
-                 USER_CONFIG_UNIT_PATH,
-                 "/etc/systemd/user",
-+                "/etc/systemd-mutable/user",
-                 NULL
-         };
- 
-         const char * const runtime_unit_path = "/run/systemd/user";
- 
-         const char * const data_unit_paths[] = {
--                "/usr/local/lib/systemd/user",
--                "/usr/local/share/systemd/user",
-                 USER_DATA_UNIT_PATH,
--                "/usr/lib/systemd/user",
--                "/usr/share/systemd/user",
-                 NULL
-         };
- 
-@@ -260,13 +257,11 @@ int lookup_paths_init(
-                                         STRV_IFNOTNULL(generator_early),
-                                         USER_CONFIG_UNIT_PATH,
-                                         "/etc/systemd/user",
-+                                        "/etc/systemd-mutable/user",
-+                                        "/nix/var/nix/profiles/default/lib/systemd/user",
-                                         "/run/systemd/user",
-                                         STRV_IFNOTNULL(generator),
--                                        "/usr/local/lib/systemd/user",
--                                        "/usr/local/share/systemd/user",
-                                         USER_DATA_UNIT_PATH,
--                                        "/usr/lib/systemd/user",
--                                        "/usr/share/systemd/user",
-                                         STRV_IFNOTNULL(generator_late),
-                                         NULL);
-                 } else
-@@ -276,14 +271,11 @@ int lookup_paths_init(
-                                 STRV_IFNOTNULL(generator_early),
-                                 SYSTEM_CONFIG_UNIT_PATH,
-                                 "/etc/systemd/system",
-+                                "/etc/systemd-mutable/system",
-+                                "/nix/var/nix/profiles/default/lib/systemd/system",
-                                 "/run/systemd/system",
-                                 STRV_IFNOTNULL(generator),
--                                "/usr/local/lib/systemd/system",
-                                 SYSTEM_DATA_UNIT_PATH,
--                                "/usr/lib/systemd/system",
--#ifdef HAVE_SPLIT_USR
--                                "/lib/systemd/system",
--#endif
-                                 STRV_IFNOTNULL(generator_late),
-                                 NULL);
- 
-diff --git a/src/shared/path-util.c b/src/shared/path-util.c
-index 67566bc..be03695 100644
---- a/src/shared/path-util.c
-+++ b/src/shared/path-util.c
-@@ -563,11 +563,11 @@ int path_is_os_tree(const char *path) {
-         return r >= 0;
- }
- 
--int find_binary(const char *name, char **filename) {
-+int find_binary(const char *name, bool local, char **filename) {
-         assert(name);
- 
-         if (is_path(name)) {
--                if (access(name, X_OK) < 0)
-+                if (local && access(name, X_OK) < 0)
-                         return -errno;
- 
-                 if (filename) {
-@@ -657,7 +657,7 @@ int fsck_exists(const char *fstype) {
- 
-         checker = strappenda("fsck.", fstype);
- 
--        r = find_binary(checker, &p);
-+        r = find_binary(checker, true, &p);
-         if (r < 0)
-                 return r;
- 
-diff --git a/src/shared/path-util.h b/src/shared/path-util.h
-index 8d171a5..bd0d324 100644
---- a/src/shared/path-util.h
-+++ b/src/shared/path-util.h
-@@ -55,7 +55,7 @@ int path_is_mount_point(const char *path, bool allow_symlink);
- int path_is_read_only_fs(const char *path);
- int path_is_os_tree(const char *path);
- 
--int find_binary(const char *name, char **filename);
-+int find_binary(const char *name, bool local, char **filename);
- 
- bool paths_check_timestamp(const char* const* paths, usec_t *paths_ts_usec, bool update);
- 
-diff --git a/src/shared/virt.c b/src/shared/virt.c
-index f9c4e67..f3104d5 100644
---- a/src/shared/virt.c
-+++ b/src/shared/virt.c
-@@ -151,7 +151,7 @@ int detect_vm(const char **id) {
-         _cleanup_free_ char *domcap = NULL, *cpuinfo_contents = NULL;
-         static thread_local int cached_found = -1;
-         static thread_local const char *cached_id = NULL;
--        const char *_id = NULL;
-+        const char *_id = NULL, *_id_cpuid = NULL;
-         int r;
- 
-         if (_likely_(cached_found >= 0)) {
-@@ -197,10 +197,26 @@ int detect_vm(const char **id) {
- 
-         /* this will set _id to "other" and return 0 for unknown hypervisors */
-         r = detect_vm_cpuid(&_id);
--        if (r != 0)
-+
-+        /* finish when found a known hypervisor other than kvm */
-+        if (r < 0 || (r > 0 && !streq(_id, "kvm")))
-                 goto finish;
- 
-+        _id_cpuid = _id;
-+
-         r = detect_vm_dmi(&_id);
-+
-+        /* kvm with and without Virtualbox */
-+        if (streq_ptr(_id_cpuid, "kvm")) {
-+                if (r > 0 && streq(_id, "oracle"))
-+                        goto finish;
-+
-+                _id = _id_cpuid;
-+                r = 1;
-+                goto finish;
-+        }
-+
-+        /* information from dmi */
-         if (r != 0)
-                 goto finish;
- 
-@@ -293,8 +309,26 @@ int detect_container(const char **id) {
- 
-                 r = read_one_line_file("/run/systemd/container", &m);
-                 if (r == -ENOENT) {
--                        r = 0;
--                        goto finish;
-+
-+                        /* Fallback for cases where PID 1 was not
-+                         * systemd (for example, cases where
-+                         * init=/bin/sh is used. */
-+
-+                        r = getenv_for_pid(1, "container", &m);
-+                        if (r <= 0) {
-+
-+                                /* If that didn't work, give up,
-+                                 * assume no container manager.
-+                                 *
-+                                 * Note: This means we still cannot
-+                                 * detect containers if init=/bin/sh
-+                                 * is passed but privileges dropped,
-+                                 * as /proc/1/environ is only readable
-+                                 * with privileges. */
-+
-+                                r = 0;
-+                                goto finish;
-+                        }
-                 }
-                 if (r < 0)
-                         return r;
-diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
-index 28eaa6a..3866308 100644
---- a/src/systemctl/systemctl.c
-+++ b/src/systemctl/systemctl.c
-@@ -2651,7 +2651,7 @@ static int start_unit_one(
- 
-                 log_debug("Adding %s to the set", p);
-                 r = set_consume(s, p);
--                if (r < 0)
-+                if (r < 0 && r != -EEXIST)
-                         return log_oom();
-         }
- 
-@@ -6917,8 +6917,13 @@ done:
- 
- static int halt_now(enum action a) {
- 
--/* Make sure C-A-D is handled by the kernel from this
--         * point on... */
-+        /* The kernel will automaticall flush ATA disks and suchlike
-+         * on reboot(), but the file systems need to be synce'd
-+         * explicitly in advance. */
-+        sync();
-+
-+        /* Make sure C-A-D is handled by the kernel from this point
-+         * on... */
-         reboot(RB_ENABLE_CAD);
- 
-         switch (a) {
-diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h
-index eb24372..00237a2 100644
---- a/src/systemd/sd-journal.h
-+++ b/src/systemd/sd-journal.h
-@@ -138,13 +138,15 @@ int sd_journal_reliable_fd(sd_journal *j);
- int sd_journal_get_catalog(sd_journal *j, char **text);
- int sd_journal_get_catalog_for_message_id(sd_id128_t id, char **text);
- 
-+/* the inverse condition avoids ambiguity of danling 'else' after the macro */
- #define SD_JOURNAL_FOREACH(j)                                           \
--        if (sd_journal_seek_head(j) >= 0)                               \
--                while (sd_journal_next(j) > 0)
-+        if (sd_journal_seek_head(j) < 0) { }                            \
-+        else while (sd_journal_next(j) > 0)
- 
-+/* the inverse condition avoids ambiguity of danling 'else' after the macro */
- #define SD_JOURNAL_FOREACH_BACKWARDS(j)                                 \
--        if (sd_journal_seek_tail(j) >= 0)                               \
--                while (sd_journal_previous(j) > 0)
-+        if (sd_journal_seek_tail(j) < 0) { }                            \
-+        else while (sd_journal_previous(j) > 0)
- 
- #define SD_JOURNAL_FOREACH_DATA(j, data, l)                             \
-         for (sd_journal_restart_data(j); sd_journal_enumerate_data((j), &(data), &(l)) > 0; )
-diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
-index 63d64b2..57264de 100644
---- a/src/test/test-path-util.c
-+++ b/src/test/test-path-util.c
-@@ -85,29 +85,30 @@ static void test_path(void) {
-         }
- }
- 
--static void test_find_binary(const char *self) {
-+static void test_find_binary(const char *self, bool local) {
-         char *p;
- 
--        assert_se(find_binary("/bin/sh", &p) == 0);
-+        assert_se(find_binary("/bin/sh", local, &p) == 0);
-         puts(p);
-         assert_se(streq(p, "/bin/sh"));
-         free(p);
- 
--        assert_se(find_binary(self, &p) == 0);
-+        assert_se(find_binary(self, local, &p) == 0);
-         puts(p);
-         assert_se(endswith(p, "/test-path-util"));
-         assert_se(path_is_absolute(p));
-         free(p);
- 
--        assert_se(find_binary("sh", &p) == 0);
-+        assert_se(find_binary("sh", local, &p) == 0);
-         puts(p);
-         assert_se(endswith(p, "/sh"));
-         assert_se(path_is_absolute(p));
-         free(p);
- 
--        assert_se(find_binary("xxxx-xxxx", &p) == -ENOENT);
-+        assert_se(find_binary("xxxx-xxxx", local, &p) == -ENOENT);
- 
--        assert_se(find_binary("/some/dir/xxxx-xxxx", &p) == -ENOENT);
-+        assert_se(find_binary("/some/dir/xxxx-xxxx", local, &p) ==
-+                  (local ? -ENOENT : 0));
- }
- 
- static void test_prefixes(void) {
-@@ -244,7 +245,8 @@ static void test_strv_resolve(void) {
- 
- int main(int argc, char **argv) {
-         test_path();
--        test_find_binary(argv[0]);
-+        test_find_binary(argv[0], true);
-+        test_find_binary(argv[0], false);
-         test_prefixes();
-         test_path_join();
-         test_fsck_exists();
-diff --git a/src/udev/udevd.c b/src/udev/udevd.c
-index 2e6c713..193702c 100644
---- a/src/udev/udevd.c
-+++ b/src/udev/udevd.c
-@@ -994,9 +994,9 @@ static void kernel_cmdline_options(struct udev *udev) {
-                         if (r < 0)
-                                 log_warning("Invalid udev.exec-delay ignored: %s", opt + 16);
-                 } else if (startswith(opt, "udev.event-timeout=")) {
--                        r = safe_atou64(opt + 16, &arg_event_timeout_usec);
-+                        r = safe_atou64(opt + 19, &arg_event_timeout_usec);
-                         if (r < 0) {
--                                log_warning("Invalid udev.event-timeout ignored: %s", opt + 16);
-+                                log_warning("Invalid udev.event-timeout ignored: %s", opt + 19);
-                                 break;
-                         }
-                         arg_event_timeout_usec *= USEC_PER_SEC;
-diff --git a/units/console-getty.service.m4.in b/units/console-getty.service.m4.in
-index 8ac51a4..cae9fb5 100644
---- a/units/console-getty.service.m4.in
-+++ b/units/console-getty.service.m4.in
-@@ -15,7 +15,6 @@ After=rc-local.service
- Before=getty.target
- 
- [Service]
--ExecStart=-/sbin/agetty --noclear --keep-baud console 115200,38400,9600 $TERM
- Type=idle
- Restart=always
- RestartSec=0
-diff --git a/units/container-getty@.service.m4.in b/units/container-getty@.service.m4.in
-index 4f7794b..6dfc2e9 100644
---- a/units/container-getty@.service.m4.in
-+++ b/units/container-getty@.service.m4.in
-@@ -14,9 +14,9 @@ After=rc-local.service
- )m4_dnl
- Before=getty.target
- IgnoreOnIsolate=yes
-+ConditionPathExists=/dev/pts/%I
- 
- [Service]
--ExecStart=-/sbin/agetty --noclear --keep-baud pts/%I 115200,38400,9600 $TERM
- Type=idle
- Restart=always
- RestartSec=0
-diff --git a/units/emergency.service.in b/units/emergency.service.in
-index 18973e7..3a99660 100644
---- a/units/emergency.service.in
-+++ b/units/emergency.service.in
-@@ -16,7 +16,6 @@ Before=shutdown.target
- [Service]
- Environment=HOME=/root
- WorkingDirectory=/root
--ExecStartPre=-/bin/plymouth quit
- ExecStartPre=-/bin/echo -e 'Welcome to emergency mode! After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" or ^D to\\ntry again to boot into default mode.'
- ExecStart=-/bin/sh -c "/sbin/sulogin; @SYSTEMCTL@ --fail --no-block default"
- Type=idle
-diff --git a/units/getty@.service.m4 b/units/getty@.service.m4
-index 46164ab..f194a31 100644
---- a/units/getty@.service.m4
-+++ b/units/getty@.service.m4
-@@ -23,11 +23,12 @@ IgnoreOnIsolate=yes
- # On systems without virtual consoles, don't start any getty. Note
- # that serial gettys are covered by serial-getty@.service, not this
- # unit.
--ConditionPathExists=/dev/tty0
-+ConditionPathExists=|/dev/tty0
-+ConditionVirtualization=|lxc
-+ConditionVirtualization=|lxc-libvirt
- 
- [Service]
- # the VT is cleared by TTYVTDisallocate
--ExecStart=-/sbin/agetty --noclear %I $TERM
- Type=idle
- Restart=always
- RestartSec=0
-diff --git a/units/kmod-static-nodes.service.in b/units/kmod-static-nodes.service.in
-index 0934a87..7e30c9e 100644
---- a/units/kmod-static-nodes.service.in
-+++ b/units/kmod-static-nodes.service.in
-@@ -10,7 +10,6 @@ Description=Create list of required static device nodes for the current kernel
- DefaultDependencies=no
- Before=sysinit.target systemd-tmpfiles-setup-dev.service
- ConditionCapability=CAP_SYS_MODULE
--ConditionPathExists=/lib/modules/%v/modules.devname
- 
- [Service]
- Type=oneshot
-diff --git a/units/local-fs.target b/units/local-fs.target
-index d2e5429..d26984b 100644
---- a/units/local-fs.target
-+++ b/units/local-fs.target
-@@ -13,3 +13,5 @@ Conflicts=shutdown.target
- After=local-fs-pre.target
- OnFailure=emergency.target
- OnFailureJobMode=replace-irreversibly
-+
-+X-StopOnReconfiguration=yes
-diff --git a/units/remote-fs.target b/units/remote-fs.target
-index 43ffa5c..156a681 100644
---- a/units/remote-fs.target
-+++ b/units/remote-fs.target
-@@ -12,5 +12,7 @@ After=remote-fs-pre.target
- DefaultDependencies=no
- Conflicts=shutdown.target
- 
-+X-StopOnReconfiguration=yes
-+
- [Install]
- WantedBy=multi-user.target
-diff --git a/units/rescue.service.in b/units/rescue.service.in
-index fc93f1e..3c87cf8 100644
---- a/units/rescue.service.in
-+++ b/units/rescue.service.in
-@@ -16,7 +16,6 @@ Before=shutdown.target
- [Service]
- Environment=HOME=/root
- WorkingDirectory=/root
--ExecStartPre=-/bin/plymouth quit
- ExecStartPre=-/bin/echo -e 'Welcome to emergency mode! After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" or ^D to\\nboot into default mode.'
- ExecStart=-/bin/sh -c "/sbin/sulogin; @SYSTEMCTL@ --fail --no-block default"
- Type=idle
-diff --git a/units/serial-getty@.service.m4 b/units/serial-getty@.service.m4
-index 4522d0d..96daa5c 100644
---- a/units/serial-getty@.service.m4
-+++ b/units/serial-getty@.service.m4
-@@ -22,7 +22,6 @@ Before=getty.target
- IgnoreOnIsolate=yes
- 
- [Service]
--ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM
- Type=idle
- Restart=always
- UtmpIdentifier=%I
-diff --git a/units/sysinit.target b/units/sysinit.target
-index ec33503..4ac47b9 100644
---- a/units/sysinit.target
-+++ b/units/sysinit.target
-@@ -9,5 +9,4 @@
- Description=System Initialization
- Documentation=man:systemd.special(7)
- Conflicts=emergency.service emergency.target
--Wants=local-fs.target swap.target
--After=local-fs.target swap.target emergency.service emergency.target
-+After=emergency.service emergency.target
-diff --git a/units/systemd-backlight@.service.in b/units/systemd-backlight@.service.in
-index ecf3de4..7e83446 100644
---- a/units/systemd-backlight@.service.in
-+++ b/units/systemd-backlight@.service.in
-@@ -19,3 +19,4 @@ Type=oneshot
- RemainAfterExit=yes
- ExecStart=@rootlibexecdir@/systemd-backlight load %i
- ExecStop=@rootlibexecdir@/systemd-backlight save %i
-+X-RestartIfChanged=false
-diff --git a/units/systemd-journal-flush.service.in b/units/systemd-journal-flush.service.in
-index 699670b..ba22c6d 100644
---- a/units/systemd-journal-flush.service.in
-+++ b/units/systemd-journal-flush.service.in
-@@ -10,8 +10,10 @@ Description=Trigger Flushing of 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
-+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@/journalctl --flush
-diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
-index 4de38fa..2f23c13 100644
---- a/units/systemd-journald.service.in
-+++ b/units/systemd-journald.service.in
-@@ -14,6 +14,7 @@ After=systemd-journald.socket systemd-journald-dev-log.socket syslog.socket
- Before=sysinit.target
- 
- [Service]
-+Type=notify
- Sockets=systemd-journald.socket systemd-journald-dev-log.socket
- ExecStart=@rootlibexecdir@/systemd-journald
- Restart=always
-@@ -26,3 +27,8 @@ WatchdogSec=1min
- # Increase the default a bit in order to allow many simultaneous
- # services being run since we keep one fd open per service.
- LimitNOFILE=16384
-+
-+# Don't restart journald, since that causes services connected to
-+# journald to stop logging (see
-+# https://bugs.freedesktop.org/show_bug.cgi?id=56043).
-+X-RestartIfChanged=no
-diff --git a/units/systemd-random-seed.service.in b/units/systemd-random-seed.service.in
-index b55844b..3ef9fc6 100644
---- a/units/systemd-random-seed.service.in
-+++ b/units/systemd-random-seed.service.in
-@@ -19,3 +19,4 @@ Type=oneshot
- RemainAfterExit=yes
- ExecStart=@rootlibexecdir@/systemd-random-seed load
- ExecStop=@rootlibexecdir@/systemd-random-seed save
-+X-RestartIfChanged=false
-diff --git a/units/systemd-rfkill@.service.in b/units/systemd-rfkill@.service.in
-index 0e9851b..9f8fa0d 100644
---- a/units/systemd-rfkill@.service.in
-+++ b/units/systemd-rfkill@.service.in
-@@ -19,3 +19,4 @@ Type=oneshot
- RemainAfterExit=yes
- ExecStart=@rootlibexecdir@/systemd-rfkill load %I
- ExecStop=@rootlibexecdir@/systemd-rfkill save %I
-+X-RestartIfChanged=false
-diff --git a/units/systemd-tmpfiles-setup.service.in b/units/systemd-tmpfiles-setup.service.in
-index e895cda..194146f 100644
---- a/units/systemd-tmpfiles-setup.service.in
-+++ b/units/systemd-tmpfiles-setup.service.in
-@@ -11,7 +11,7 @@ Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
- DefaultDependencies=no
- Conflicts=shutdown.target
- After=local-fs.target systemd-sysusers.service
--Before=sysinit.target shutdown.target
-+Before=shutdown.target
- RefuseManualStop=yes
- 
- [Service]
-diff --git a/units/systemd-update-utmp.service.in b/units/systemd-update-utmp.service.in
-index 163eccd..7357c12 100644
---- a/units/systemd-update-utmp.service.in
-+++ b/units/systemd-update-utmp.service.in
-@@ -11,7 +11,7 @@ Documentation=man:systemd-update-utmp.service(8) man:utmp(5)
- DefaultDependencies=no
- RequiresMountsFor=/var/log/wtmp
- Conflicts=shutdown.target
--After=systemd-remount-fs.service systemd-tmpfiles-setup.service auditd.service
-+After=systemd-remount-fs.service auditd.service
- Before=sysinit.target shutdown.target
- 
- [Service]
-@@ -19,3 +19,4 @@ Type=oneshot
- RemainAfterExit=yes
- ExecStart=@rootlibexecdir@/systemd-update-utmp reboot
- ExecStop=@rootlibexecdir@/systemd-update-utmp shutdown
-+X-RestartIfChanged=false
-diff --git a/units/systemd-user-sessions.service.in b/units/systemd-user-sessions.service.in
-index 0869e73..b6ed958 100644
---- a/units/systemd-user-sessions.service.in
-+++ b/units/systemd-user-sessions.service.in
-@@ -15,3 +15,6 @@ Type=oneshot
- RemainAfterExit=yes
- ExecStart=@rootlibexecdir@/systemd-user-sessions start
- ExecStop=@rootlibexecdir@/systemd-user-sessions stop
-+
-+# Restart kills all active sessions.
-+X-RestartIfChanged=no
diff --git a/pkgs/os-specific/linux/udisks/2-default.nix b/pkgs/os-specific/linux/udisks/2-default.nix
index 76d6caa767c..060d9ad1dd3 100644
--- a/pkgs/os-specific/linux/udisks/2-default.nix
+++ b/pkgs/os-specific/linux/udisks/2-default.nix
@@ -1,6 +1,6 @@
 { stdenv, fetchurl, pkgconfig, intltool
 , expat, acl, systemd, glib, libatasmart, polkit
-, libxslt, docbook_xsl, utillinux, mdadm
+, libxslt, docbook_xsl, utillinux, mdadm, libgudev
 }:
 
 stdenv.mkDerivation rec {
@@ -26,9 +26,7 @@ stdenv.mkDerivation rec {
 
   nativeBuildInputs = [ pkgconfig intltool ];
 
-  propagatedBuildInputs = [ expat acl systemd glib libatasmart polkit ]; # in closure anyway
-
-  buildInputs = [ libxslt docbook_xsl ];
+  buildInputs = [ libxslt docbook_xsl libgudev expat acl systemd glib libatasmart polkit ];
 
   configureFlags = [
     "--localstatedir=/var"
diff --git a/pkgs/os-specific/linux/upower/default.nix b/pkgs/os-specific/linux/upower/default.nix
index 66b9c34ab51..0f7f93a5741 100644
--- a/pkgs/os-specific/linux/upower/default.nix
+++ b/pkgs/os-specific/linux/upower/default.nix
@@ -1,5 +1,5 @@
 { stdenv, fetchurl, pkgconfig, glib, dbus_glib
-, intltool, libxslt, docbook_xsl, udev, libusb1
+, intltool, libxslt, docbook_xsl, udev, libgudev, libusb1
 , useSystemd ? true, systemd, gobjectIntrospection
 }:
 
@@ -14,7 +14,7 @@ stdenv.mkDerivation rec {
   };
 
   buildInputs =
-    [ dbus_glib intltool libxslt docbook_xsl udev libusb1 gobjectIntrospection ]
+    [ dbus_glib intltool libxslt docbook_xsl udev libgudev libusb1 gobjectIntrospection ]
     ++ stdenv.lib.optional useSystemd systemd;
 
   nativeBuildInputs = [ pkgconfig ];
diff --git a/pkgs/os-specific/linux/util-linux/default.nix b/pkgs/os-specific/linux/util-linux/default.nix
index 7768875ca57..bcd9aa58bcc 100644
--- a/pkgs/os-specific/linux/util-linux/default.nix
+++ b/pkgs/os-specific/linux/util-linux/default.nix
@@ -1,13 +1,15 @@
 { stdenv, fetchurl, zlib, ncurses ? null, perl ? null, pam }:
 
 stdenv.mkDerivation rec {
-  name = "util-linux-2.26.2";
+  name = "util-linux-2.27.1";
 
   src = fetchurl {
-    url = "mirror://kernel/linux/utils/util-linux/v2.26/${name}.tar.xz";
-    sha256 = "0rlnzmiqdannzf81fbh41541lrck63v9zhskm6h4i2jj8ahvsa8f";
+    url = "mirror://kernel/linux/utils/util-linux/v2.27/${name}.tar.xz";
+    sha256 = "1452hz5zx56a3mad8yrg5wb0vy5zi19mpjp6zx1yr6p9xp6qz08a";
   };
 
+  outputs = [ "out" "man" ];
+
   patches = [
     ./rtcwake-search-PATH-for-shutdown.patch
   ];
diff --git a/pkgs/os-specific/linux/util-linux/rtcwake-search-PATH-for-shutdown.patch b/pkgs/os-specific/linux/util-linux/rtcwake-search-PATH-for-shutdown.patch
index 92cb07d4383..68970c655f1 100644
--- a/pkgs/os-specific/linux/util-linux/rtcwake-search-PATH-for-shutdown.patch
+++ b/pkgs/os-specific/linux/util-linux/rtcwake-search-PATH-for-shutdown.patch
@@ -4,10 +4,10 @@ distros anyway).
 
   -- nckx <tobias.geerinckx.rice@gmail.com>
 
-diff -Naur a/include/pathnames.h b/include/pathnames.h
---- a/include/pathnames.h	2014-09-16 14:37:06.138551680 +0200
-+++ b/include/pathnames.h	2015-01-01 20:41:02.510948314 +0100
-@@ -43,7 +43,7 @@
+diff -ru util-linux-2.27-orig/include/pathnames.h util-linux-2.27/include/pathnames.h
+--- util-linux-2.27-orig/include/pathnames.h	2015-06-29 13:13:14.669847478 +0200
++++ util-linux-2.27/include/pathnames.h	2015-10-07 20:09:17.401022602 +0200
+@@ -54,7 +54,7 @@
  #define _PATH_INITTAB		"/etc/inittab"
  #define _PATH_RC		"/etc/rc"
  #define _PATH_REBOOT		"/sbin/reboot"
@@ -16,15 +16,15 @@ diff -Naur a/include/pathnames.h b/include/pathnames.h
  #define _PATH_SINGLE		"/etc/singleboot"
  #define _PATH_SHUTDOWN_CONF	"/etc/shutdown.conf"
  
-diff -Naur a/sys-utils/rtcwake.c b/sys-utils/rtcwake.c
---- a/sys-utils/rtcwake.c	2014-10-24 11:21:20.447389309 +0200
-+++ b/sys-utils/rtcwake.c	2015-01-01 20:57:59.398911209 +0100
-@@ -582,7 +582,7 @@
+diff -ru util-linux-2.27-orig/sys-utils/rtcwake.c util-linux-2.27/sys-utils/rtcwake.c
+--- util-linux-2.27-orig/sys-utils/rtcwake.c	2015-08-05 11:32:44.453821232 +0200
++++ util-linux-2.27/sys-utils/rtcwake.c	2015-10-07 20:09:37.834032536 +0200
+@@ -576,7 +576,7 @@
+ 		arg[i++] = "now";
  		arg[i]   = NULL;
- 
- 		if (!dryrun) {
+ 		if (!ctl.dryrun) {
 -			execv(arg[0], arg);
 +			execvp(arg[0], arg);
- 
  			warn(_("failed to execute %s"), _PATH_SHUTDOWN);
  			rc = EXIT_FAILURE;
+ 		}