diff options
Diffstat (limited to 'pkgs/os-specific/linux')
21 files changed, 363 insertions, 2710 deletions
diff --git a/pkgs/os-specific/linux/apparmor/2.9/default.nix b/pkgs/os-specific/linux/apparmor/2.9/default.nix new file mode 100644 index 000000000000..5e8ccc756918 --- /dev/null +++ b/pkgs/os-specific/linux/apparmor/2.9/default.nix @@ -0,0 +1,183 @@ +{ stdenv, fetchurl, autoconf, automake, libtool, pkgconfig, perl, which +, glibc, flex, bison, python27, swig, dbus, pam +}: + +let + apparmor-series = "2.9"; + apparmor-patchver = "2"; + apparmor-version = "${apparmor-series}.${apparmor-patchver}"; + + apparmor-meta = component: with stdenv.lib; { + homepage = http://apparmor.net/; + description = "Linux application security system - ${component}"; + license = licenses.gpl2; + maintainers = with maintainers; [ phreedom thoughtpolice joachifm ]; + platforms = platforms.linux; + }; + + apparmor-sources = fetchurl { + url = "https://launchpad.net/apparmor/${apparmor-series}/${apparmor-version}/+download/apparmor-${apparmor-version}.tar.gz"; + sha256 = "1mayly7d7w959fya7z8q6kab2x3jcwhqhkpx36jsvpjhxkhmc4fh"; + }; + + prePatchCommon = '' + substituteInPlace ./common/Make.rules --replace "/usr/bin/pod2man" "${perl}/bin/pod2man" + substituteInPlace ./common/Make.rules --replace "/usr/bin/pod2html" "${perl}/bin/pod2html" + substituteInPlace ./common/Make.rules --replace "/usr/include/linux/capability.h" "${glibc.dev}/include/linux/capability.h" + substituteInPlace ./common/Make.rules --replace "/usr/share/man" "share/man" + ''; + + libapparmor = stdenv.mkDerivation { + name = "libapparmor-${apparmor-version}"; + src = apparmor-sources; + + buildInputs = [ + autoconf + automake + bison + flex + dbus # requires patch to dbus ... + glibc + libtool + perl + pkgconfig + python27 + swig + which + ]; + + prePatch = prePatchCommon + '' + substituteInPlace ./libraries/libapparmor/src/Makefile.am --replace "/usr/include/netinet/in.h" "${glibc.dev}/include/netinet/in.h" + substituteInPlace ./libraries/libapparmor/src/Makefile.in --replace "/usr/include/netinet/in.h" "${glibc.dev}/include/netinet/in.h" + ''; + + buildPhase = '' + cd ./libraries/libapparmor + ./autogen.sh + ./configure --prefix="$out" --with-python --with-perl + make + ''; + + installPhase = '' + make install + ''; + + meta = apparmor-meta "library"; + }; + + apparmor-utils = stdenv.mkDerivation { + name = "apparmor-utils-${apparmor-version}"; + src = apparmor-sources; + + buildInputs = [ + python27 + libapparmor + which + ]; + + prePatch = prePatchCommon; + + buildPhase = '' + cd ./utils + make LANGS="" + ''; + + installPhase = '' + make install LANGS="" DESTDIR="$out" BINDIR="$out/bin" VIM_INSTALL_PATH="$out/share" PYPREFIX="" + ''; + + meta = apparmor-meta "user-land utilities"; + }; + + apparmor-parser = stdenv.mkDerivation { + name = "apparmor-parser-${apparmor-version}"; + src = apparmor-sources; + + buildInputs = [ + libapparmor + bison + flex + which + ]; + + prePatch = prePatchCommon + '' + substituteInPlace ./parser/Makefile --replace "/usr/bin/bison" "${bison}/bin/bison" + substituteInPlace ./parser/Makefile --replace "/usr/bin/flex" "${flex}/bin/flex" + substituteInPlace ./parser/Makefile --replace "/usr/include/linux/capability.h" "${glibc.dev}/include/linux/capability.h" + ## techdoc.pdf still doesn't build ... + substituteInPlace ./parser/Makefile --replace "manpages htmlmanpages pdf" "manpages htmlmanpages" + ''; + + buildPhase = '' + cd ./parser + make LANGS="" USE_SYSTEM=1 INCLUDEDIR=${libapparmor}/include + ''; + + installPhase = '' + make install LANGS="" USE_SYSTEM=1 INCLUDEDIR=${libapparmor}/include DESTDIR="$out" DISTRO="unknown" + ''; + + meta = apparmor-meta "rule parser"; + }; + + apparmor-pam = stdenv.mkDerivation { + name = "apparmor-pam-${apparmor-version}"; + src = apparmor-sources; + + buildInputs = [ + libapparmor + pam + pkgconfig + which + ]; + + buildPhase = '' + cd ./changehat/pam_apparmor + make USE_SYSTEM=1 + ''; + + installPhase = '' + make install DESTDIR="$out" + ''; + + meta = apparmor-meta "PAM service"; + }; + + apparmor-profiles = stdenv.mkDerivation { + name = "apparmor-profiles-${apparmor-version}"; + src = apparmor-sources; + + buildInputs = [ which ]; + + buildPhase = '' + cd ./profiles + make + ''; + + installPhase = '' + make install DESTDIR="$out" EXTRAS_DEST="$out/share/apparmor/extra-profiles" + ''; + + meta = apparmor-meta "profiles"; + }; + + apparmor-kernel-patches = stdenv.mkDerivation { + name = "apparmor-kernel-patches-${apparmor-version}"; + src = apparmor-sources; + + phases = ''unpackPhase installPhase''; + + installPhase = '' + mkdir "$out" + cp -R ./kernel-patches "$out" + ''; + + meta = apparmor-meta "kernel patches"; + }; + +in + +{ + inherit libapparmor apparmor-utils apparmor-parser apparmor-pam + apparmor-profiles apparmor-kernel-patches; +} diff --git a/pkgs/os-specific/linux/checksec/default.nix b/pkgs/os-specific/linux/checksec/default.nix index b423dc3a0862..60468538be24 100644 --- a/pkgs/os-specific/linux/checksec/default.nix +++ b/pkgs/os-specific/linux/checksec/default.nix @@ -21,7 +21,7 @@ stdenv.mkDerivation rec { cp checksec.sh $out/bin/checksec chmod +x $out/bin/checksec substituteInPlace $out/bin/checksec --replace /bin/bash ${stdenv.shell} - substituteInPlace $out/bin/checksec --replace /lib/libc.so.6 ${glibc}/lib/libc.so.6 + substituteInPlace $out/bin/checksec --replace /lib/libc.so.6 ${glibc.out}/lib/libc.so.6 substituteInPlace $out/bin/checksec --replace find ${findutils}/bin/find substituteInPlace $out/bin/checksec --replace "file $" "${file}/bin/file $" substituteInPlace $out/bin/checksec --replace "xargs file" "xargs ${file}/bin/file" diff --git a/pkgs/os-specific/linux/drbd/default.nix b/pkgs/os-specific/linux/drbd/default.nix index 4c945a7fbac7..3491cf713917 100644 --- a/pkgs/os-specific/linux/drbd/default.nix +++ b/pkgs/os-specific/linux/drbd/default.nix @@ -18,7 +18,7 @@ stdenv.mkDerivation rec { preConfigure = '' - export PATH=${udev}/sbin:$PATH + export PATH=${udev.out}/sbin:$PATH substituteInPlace user/Makefile.in --replace /sbin/ $out/sbin/ substituteInPlace user/legacy/Makefile.in \ --replace /sbin/ $out/sbin/ \ diff --git a/pkgs/os-specific/linux/kbd/default.nix b/pkgs/os-specific/linux/kbd/default.nix index bb2915958f7c..fddaa84a8240 100644 --- a/pkgs/os-specific/linux/kbd/default.nix +++ b/pkgs/os-specific/linux/kbd/default.nix @@ -40,7 +40,7 @@ stdenv.mkDerivation rec { # Fix the path to gzip/bzip2. substituteInPlace src/libkeymap/findfile.c \ --replace gzip ${gzip}/bin/gzip \ - --replace bzip2 ${bzip2}/bin/bzip2 \ + --replace bzip2 ${bzip2.bin}/bin/bzip2 \ # We get a warning in armv5tel-linux and the fuloong2f, so we # disable -Werror in it. 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 d9d0ce7e3b3d..000000000000 --- 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 2fd34c68edc6..0cc38a0548ca 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/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix index 49880e0ecdd0..091855a16525 100644 --- a/pkgs/os-specific/linux/kernel/manual-config.nix +++ b/pkgs/os-specific/linux/kernel/manual-config.nix @@ -74,7 +74,7 @@ let installsFirmware = (config.isEnabled "FW_LOADER") && (isModular || (config.isDisabled "FIRMWARE_IN_KERNEL")); - in (optionalAttrs isModular { outputs = [ "out" "dev" ]; }) // { + in (optionalAttrs isModular { outputs = [ "out" "dev" ]; propagatedOutputs = ""; }) // { passthru = { inherit version modDirVersion config kernelPatches; }; diff --git a/pkgs/os-specific/linux/klibc/shrunk.nix b/pkgs/os-specific/linux/klibc/shrunk.nix index 066b4fcb4e06..2ce833d104fd 100644 --- a/pkgs/os-specific/linux/klibc/shrunk.nix +++ b/pkgs/os-specific/linux/klibc/shrunk.nix @@ -8,10 +8,10 @@ stdenv.mkDerivation { name = "${klibc.name}"; buildCommand = '' mkdir -p $out/lib - cp -prd ${klibc}/lib/klibc/bin $out/ - cp -p ${klibc}/lib/*.so $out/lib/ + cp -prd ${klibc.out}/lib/klibc/bin $out/ + cp -p ${klibc.out}/lib/*.so $out/lib/ chmod +w $out/* - old=$(echo ${klibc}/lib/klibc-*.so) + old=$(echo ${klibc.out}/lib/klibc-*.so) new=$(echo $out/lib/klibc-*.so) for i in $out/bin/*; do echo $i diff --git a/pkgs/os-specific/linux/libcap/default.nix b/pkgs/os-specific/linux/libcap/default.nix index 8157270d67d7..84e363b68242 100644 --- a/pkgs/os-specific/linux/libcap/default.nix +++ b/pkgs/os-specific/linux/libcap/default.nix @@ -3,12 +3,14 @@ stdenv.mkDerivation rec { name = "libcap-${version}"; version = "2.24"; - + src = fetchurl { url = "mirror://kernel/linux/libs/security/linux-privs/libcap2/${name}.tar.xz"; sha256 = "0rbc9qbqs5bp9am9s9g83wxj5k4ixps2agy9dxr1v1fwg27mdr6f"; }; - + + outputs = [ "dev" "out" ]; + nativeBuildInputs = [ perl ]; propagatedBuildInputs = [ attr ]; @@ -16,14 +18,10 @@ stdenv.mkDerivation rec { makeFlags = "lib=lib prefix=$(out)"; - passthru = { - postinst = n : '' - mkdir -p $out/share/doc/${n} - cp ../License $out/share/doc/${n}/License - ''; - }; - - postInstall = passthru.postinst name; + postInstall = '' + mkdir -p "$dev/share/doc/${name}" + cp ../License "$dev/share/doc/${name}/License" + ''; meta = { description = "Library for working with POSIX capabilities"; diff --git a/pkgs/os-specific/linux/lvm2/default.nix b/pkgs/os-specific/linux/lvm2/default.nix index 0e6bf512aa26..2ec7ff5189dd 100644 --- a/pkgs/os-specific/linux/lvm2/default.nix +++ b/pkgs/os-specific/linux/lvm2/default.nix @@ -30,7 +30,7 @@ stdenv.mkDerivation { --replace /usr/bin/tr ${coreutils}/bin/tr substituteInPlace scripts/lvm2_activation_generator_systemd_red_hat.c \ --replace /usr/sbin/lvm $out/sbin/lvm \ - --replace /usr/bin/udevadm ${udev}/bin/udevadm + --replace /usr/bin/udevadm ${udev.out}/bin/udevadm sed -i /DEFAULT_SYS_DIR/d Makefile.in sed -i /DEFAULT_PROFILE_DIR/d conf/Makefile.in diff --git a/pkgs/os-specific/linux/module-init-tools/default.nix b/pkgs/os-specific/linux/module-init-tools/default.nix index 1302d7b1fef0..2d6875d506a7 100644 --- a/pkgs/os-specific/linux/module-init-tools/default.nix +++ b/pkgs/os-specific/linux/module-init-tools/default.nix @@ -20,6 +20,8 @@ stdenv.mkDerivation { }) ]; + buildInputs = [ stdenv.glibc.dev stdenv.glibc.static ]; + SGML_CATALOG_FILES = "${docbook_sgml_dtd_41}/sgml/dtd/docbook-4.1/docbook.cat"; patches = [ ./module-dir.patch ./docbook2man.patch ]; diff --git a/pkgs/os-specific/linux/multipath-tools/default.nix b/pkgs/os-specific/linux/multipath-tools/default.nix index 3da37a89923a..03c86dec4a00 100644 --- a/pkgs/os-specific/linux/multipath-tools/default.nix +++ b/pkgs/os-specific/linux/multipath-tools/default.nix @@ -22,8 +22,8 @@ stdenv.mkDerivation rec { substituteInPlace kpartx/kpartx.rules --replace /sbin/kpartx $out/sbin/kpartx substituteInPlace kpartx/kpartx_id --replace /sbin/dmsetup ${lvm2}/sbin/dmsetup - substituteInPlace libmultipath/defaults.h --replace /lib/udev/scsi_id ${udev}/lib/udev/scsi_id - substituteInPlace libmultipath/hwtable.c --replace /lib/udev/scsi_id ${udev}/lib/udev/scsi_id + substituteInPlace libmultipath/defaults.h --replace /lib/udev/scsi_id ${udev.libudev}/lib/udev/scsi_id + substituteInPlace libmultipath/hwtable.c --replace /lib/udev/scsi_id ${udev.libudev}/lib/udev/scsi_id ''; meta = { diff --git a/pkgs/os-specific/linux/nfs-utils/default.nix b/pkgs/os-specific/linux/nfs-utils/default.nix index 75f25e268042..34cf0196079b 100644 --- a/pkgs/os-specific/linux/nfs-utils/default.nix +++ b/pkgs/os-specific/linux/nfs-utils/default.nix @@ -21,7 +21,7 @@ stdenv.mkDerivation rec { "--with-statedir=/var/lib/nfs" "--with-tirpcinclude=${libtirpc}/include/tirpc" ] - ++ stdenv.lib.optional (stdenv ? glibc) "--with-rpcgen=${stdenv.glibc}/bin/rpcgen"; + ++ stdenv.lib.optional (stdenv ? glibc) "--with-rpcgen=${stdenv.glibc.bin}/bin/rpcgen"; patchPhase = '' diff --git a/pkgs/os-specific/linux/pam/default.nix b/pkgs/os-specific/linux/pam/default.nix index f7cadd469d70..d84c6224eebe 100644 --- a/pkgs/os-specific/linux/pam/default.nix +++ b/pkgs/os-specific/linux/pam/default.nix @@ -9,10 +9,14 @@ stdenv.mkDerivation rec { sha256 = "1n9lnf9gjs72kbj1g354v1xhi2j27aqaah15vykh7cnkq08i4arl"; }; + outputs = [ "out" "doc" "man" /* "modules" */ ]; + nativeBuildInputs = [ flex ]; buildInputs = [ cracklib ]; + enableParallelBuilding = true; + crossAttrs = { propagatedBuildInputs = [ flex.crossDrv cracklib.crossDrv ]; preConfigure = preConfigure + '' @@ -31,7 +35,14 @@ stdenv.mkDerivation rec { postInstall = '' mv -v $out/sbin/unix_chkpwd{,.orig} ln -sv /var/setuid-wrappers/unix_chkpwd $out/sbin/unix_chkpwd - ''; + ''; /* + rm -rf $out/etc + mkdir -p $modules/lib + mv $out/lib/security $modules/lib/ + '';*/ + # don't move modules, because libpam needs to (be able to) find them, + # which is done by dlopening $out/lib/security/pam_foo.so + # $out/etc was also missed: pam_env(login:session): Unable to open config file preConfigure = '' configureFlags="$configureFlags --includedir=$out/include/security" diff --git a/pkgs/os-specific/linux/shadow/default.nix b/pkgs/os-specific/linux/shadow/default.nix index f928dc8e657c..321e94e3aaf4 100644 --- a/pkgs/os-specific/linux/shadow/default.nix +++ b/pkgs/os-specific/linux/shadow/default.nix @@ -37,7 +37,7 @@ stdenv.mkDerivation rec { preBuild = assert glibc != null; '' - substituteInPlace lib/nscd.c --replace /usr/sbin/nscd ${glibc}/sbin/nscd + substituteInPlace lib/nscd.c --replace /usr/sbin/nscd ${glibc.bin}/bin/nscd ''; postInstall = diff --git a/pkgs/os-specific/linux/systemd/default.nix b/pkgs/os-specific/linux/systemd/default.nix index b7f70ec3b117..ca0a4ba23b40 100644 --- a/pkgs/os-specific/linux/systemd/default.nix +++ b/pkgs/os-specific/linux/systemd/default.nix @@ -1,7 +1,8 @@ -{ stdenv, fetchurl, pkgconfig, intltool, gperf, libcap, dbus, kmod -, xz, pam, acl, cryptsetup, libuuid, m4, utillinux +{ stdenv, fetchFromGitHub, pkgconfig, intltool, gperf, libcap, dbus, kmod +, zlib, xz, pam, acl, cryptsetup, libuuid, m4, utillinux, libffi , 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 }: @@ -11,26 +12,32 @@ assert stdenv.isLinux; assert pythonSupport -> pythonPackages != null; stdenv.mkDerivation rec { - version = "217"; + version = "226"; name = "systemd-${version}"; - src = fetchurl { - url = "http://www.freedesktop.org/software/systemd/${name}.tar.xz"; - sha256 = "163l1y4p2a564d4ynfq3k3xf53j2v5s81blb6cvpn1y7rpxyccd0"; + src = fetchFromGitHub { + owner = "NixOS"; + repo = "systemd"; + rev = "16d61e9657b643cc25ff0538688eb870ce2dd4a5"; + sha256 = "07sc1x43j60d5jnps0d7bfka10fihnpgkdrfrh9iskgmc9qangjb"; }; - patches = - [ # These are all changes between upstream and - # https://github.com/NixOS/systemd/tree/nixos-v217. - ./fixes.patch - ]; + outputs = [ "out" "libudev" "doc" ]; # TODO: "dev" + # note: there are many references to ${systemd}/... + outputDev = "out"; + propagatedOutputs = "libudev"; 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 libffi + /* 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 = [ "--localstatedir=/var" "--sysconfdir=/etc" @@ -38,11 +45,9 @@ 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" - "--with-firmware-path=/root/test-firmware:/run/current-system/firmware" "--with-tty-gid=3" # tty in NixOS has gid 3 "--enable-compat-libs" # get rid of this eventually "--disable-tests" @@ -52,11 +57,15 @@ 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=" @@ -65,31 +74,39 @@ stdenv.mkDerivation rec { 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 \ - --replace /bin/mount ${utillinux}/bin/mount \ - --replace /bin/umount ${utillinux}/bin/umount \ - --replace /sbin/swapon ${utillinux}/sbin/swapon \ - --replace /sbin/swapoff ${utillinux}/sbin/swapoff \ + --replace /usr/bin/getent ${stdenv.glibc.bin}/bin/getent \ + --replace /bin/mount ${utillinux.bin}/bin/mount \ + --replace /bin/umount ${utillinux.bin}/bin/umount \ + --replace /sbin/swapon ${utillinux.bin}/sbin/swapon \ + --replace /sbin/swapoff ${utillinux.bin}/sbin/swapoff \ + --replace /sbin/fsck ${utillinux.bin}/sbin/fsck \ --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 \ --replace /usr/lib/systemd/catalog/ $out/lib/systemd/catalog/ + export NIX_CFLAGS_LINK+=" -Wl,-rpath,$libudev/lib" + 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"; + makeFlags = [ + "udevlibexecdir=$(libudev)/lib/udev" + # udev rules refer to $out, and anything but libs should probably go to $out + "udevrulesdir=$(out)/lib/udev/rules.d" + "udevhwdbdir=$(out)/lib/udev/hwdb.d" + ]; + PYTHON_BINARY = "${coreutils}/bin/env python"; # don't want a build time dependency on Python @@ -107,12 +124,7 @@ stdenv.mkDerivation rec { "-USYSTEMD_BINARY_PATH" "-DSYSTEMD_BINARY_PATH=\"/run/current-system/systemd/lib/systemd/systemd\"" ]; - # Use /var/lib/udev rather than /etc/udev for the generated hardware - # database. Upstream doesn't want this (see commit - # 1e1954f53386cb773e2a152748dd31c4d36aa2d8) because using /var is - # forbidden in early boot, but in NixOS the initrd guarantees that - # /var is mounted. - makeFlags = "hwdb_bin=/var/lib/udev/hwdb.bin"; + enableParallelBuilding = true; installFlags = [ "localstatedir=$(TMPDIR)/var" @@ -148,9 +160,34 @@ stdenv.mkDerivation rec { done rm -rf $out/etc/rpm + + rm $out/lib/*.la + + rm -rf $out/share/doc + + # "kernel-install" shouldn't be used on NixOS. + find $out -name "*kernel-install*" -exec rm {} \; + + # Move lib(g)udev to a separate output. TODO: maybe split them up + # to avoid libudev pulling glib + mkdir -p "$libudev/lib" + mv "$out"/lib/lib{,g}udev* "$libudev/lib/" + + for i in "$libudev"/lib/*.la; do + substituteInPlace $i --replace "$out" "$libudev" + done + for i in "$out"/lib/pkgconfig/{libudev,gudev-1.0}.pc; do + substituteInPlace $i --replace "libdir=$out" "libdir=$libudev" + done ''; # */ - enableParallelBuilding = true; + # some libs fail to link to liblzma and/or libffi + postFixup = let extraLibs = stdenv.lib.makeLibraryPath [ xz.out libffi.out zlib.out ]; + in '' + for f in "$out"/lib/*.so.0.*; do + patchelf --set-rpath `patchelf --print-rpath "$f"`':${extraLibs}' "$f" + done + ''; # The interface version prevents NixOS from switching to an # incompatible systemd at runtime. (Switching across reboots is @@ -167,3 +204,5 @@ stdenv.mkDerivation rec { maintainers = [ stdenv.lib.maintainers.eelco stdenv.lib.maintainers.simons ]; }; } + + diff --git a/pkgs/os-specific/linux/systemd/fixes.patch b/pkgs/os-specific/linux/systemd/fixes.patch deleted file mode 100644 index 2997c02d26d4..000000000000 --- 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/udev/145.nix b/pkgs/os-specific/linux/udev/145.nix new file mode 100644 index 000000000000..6dd551e1ce13 --- /dev/null +++ b/pkgs/os-specific/linux/udev/145.nix @@ -0,0 +1,53 @@ +{ stdenv, fetchurl, gperf, pkgconfig, glib, acl, libusb, usbutils, pciutils }: + +assert stdenv ? glibc; + +stdenv.mkDerivation rec { + name = "udev-145"; + + src = fetchurl { + url = "mirror://kernel/linux/utils/kernel/hotplug/${name}.tar.bz2"; + sha256 = "1zmibp6n7d582fqx8vmg9vb2a1435hghfpz36056bc25ccwf7yiv"; + }; + + buildInputs = [gperf pkgconfig glib acl libusb usbutils]; + + configureFlags = "--with-pci-ids-path=${pciutils}/share/pci.ids"; + + preConfigure = + '' + substituteInPlace extras/keymap/Makefile.in \ + --replace /usr/include ${stdenv.glibc.dev}/include + ''; + + postInstall = + '' + # Install some rules that really should be installed by default. + for i in 40-alsa.rules 40-infiniband.rules 40-isdn.rules 40-pilot-links.rules 64-device-mapper.rules 64-md-raid.rules; do + cp rules/packages/$i $out/libexec/rules.d/ + done + + # The path to rule_generator.functions in write_cd_rules and + # write_net_rules is broken. Also, don't store the mutable + # persistant rules in /etc/udev/rules.d but in + # /var/lib/udev/rules.d. + for i in $out/libexec/write_cd_rules $out/libexec/write_net_rules; do + substituteInPlace $i \ + --replace /lib/udev $out/libexec \ + --replace /etc/udev/rules.d /var/lib/udev/rules.d + done + + # Don't set PATH to /bin:/sbin; won't work in NixOS. + substituteInPlace $out/libexec/rule_generator.functions \ + --replace 'PATH=' '#PATH=' + + # Don't hardcore the FIRMWARE_DIRS variable; obtain it from the + # environment of the caller. + sed '3,4d' -i $out/libexec/firmware.sh + ''; + + meta = { + homepage = http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html; + description = "Udev manages the /dev filesystem"; + }; +} diff --git a/pkgs/os-specific/linux/udisks/2-default.nix b/pkgs/os-specific/linux/udisks/2-default.nix index 76d6caa767c6..060d9ad1dd32 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 66b9c34ab511..0f7f93a57410 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 7768875ca57f..66f67dbed616 100644 --- a/pkgs/os-specific/linux/util-linux/default.nix +++ b/pkgs/os-specific/linux/util-linux/default.nix @@ -1,4 +1,4 @@ -{ stdenv, fetchurl, zlib, ncurses ? null, perl ? null, pam }: +{ stdenv, fetchurl, pkgconfig, zlib, ncurses ? null, perl ? null, pam }: stdenv.mkDerivation rec { name = "util-linux-2.26.2"; @@ -12,6 +12,11 @@ stdenv.mkDerivation rec { ./rtcwake-search-PATH-for-shutdown.patch ]; + outputs = [ "bin" "out" "man" ]; # TODO: $bin is kept the first for now + # due to lots of ${utillinux}/bin occurences and headers being rather small + outputDev = "bin"; + + #FIXME: make it also work on non-nixos? postPatch = '' # Substituting store paths would create a circular dependency on systemd @@ -38,21 +43,25 @@ stdenv.mkDerivation rec { ${if ncurses == null then "--without-ncurses" else ""} ''; + makeFlags = "usrbin_execdir=$(bin)/bin usrsbin_execdir=$(bin)/sbin"; + + nativeBuildInputs = [ pkgconfig ]; buildInputs = [ zlib pam ] ++ stdenv.lib.optional (ncurses != null) ncurses ++ stdenv.lib.optional (perl != null) perl; postInstall = '' - rm $out/bin/su # su should be supplied by the su package (shadow) + rm "$bin/bin/su" # su should be supplied by the su package (shadow) ''; enableParallelBuilding = true; - meta = { + meta = with stdenv.lib; { homepage = http://www.kernel.org/pub/linux/utils/util-linux/; description = "A set of system utilities for Linux"; - platforms = stdenv.lib.platforms.linux; + license = licenses.gpl2; # also contains parts under more permissive licenses + platforms = platforms.linux; priority = 6; # lower priority than coreutils ("kill") and shadow ("login" etc.) packages }; } |