diff --git a/debian/changelog b/debian/changelog
index a8b0a9da0440a2bf813a6da7ac08076db1e64bdd..13a0c0ef9b83a83c614d24b1a472b4a49bca39d6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -7,7 +7,6 @@ systemd (247.3-1apertis1) apertis; urgency=medium
     + Don’t build against libdw, since 0.158 isn’t available in target.
     * Add /usr to non-unmountable list.
 
-
  -- Sjoerd Simons <sjoerd@collabora.com>  Tue, 16 Mar 2021 21:06:54 +0100
 
 systemd (247.3-1) unstable; urgency=medium
diff --git a/debian/patches/apertis/0001-Remove-bashisms-from-the-depmod-wrapper.patch b/debian/patches/apertis/0001-Remove-bashisms-from-the-depmod-wrapper.patch
deleted file mode 100644
index bfbd417afc501324ebbb74474dd82a15ba1de08a..0000000000000000000000000000000000000000
--- a/debian/patches/apertis/0001-Remove-bashisms-from-the-depmod-wrapper.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From fedc892fb38e059a2f675f33770ddd9e4cad235f Mon Sep 17 00:00:00 2001
-From: Denis Pynkin <denis.pynkin@collabora.com>
-Date: Thu, 24 Jan 2019 22:40:46 +0300
-Subject: [PATCH 1/3] Remove bashisms from the depmod wrapper
-
-- Use [ not [[ and -n to test for non-emptiness
-- Use for loop instead of comma expansion
-
-Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
-[ Rebased to the latest master, amended the rm call ]
-Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk>
----
- src/kernel-install/50-depmod.install | 19 +++++++++++++++----
- 1 file changed, 15 insertions(+), 4 deletions(-)
-
-diff --git a/src/kernel-install/50-depmod.install b/src/kernel-install/50-depmod.install
-index 88f550a486..78fdf6b7ea 100644
---- a/src/kernel-install/50-depmod.install
-+++ b/src/kernel-install/50-depmod.install
-@@ -1,16 +1,27 @@
--#!/bin/bash
-+#!/bin/sh
- # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
- # ex: ts=8 sw=4 sts=4 et filetype=sh
- 
--[[ $2 ]] || exit 1
-+[ -n "$2" ] || exit 1
- 
- case "$1" in
-     add)
--        [[ -d /lib/modules/"$2"/kernel ]] || exit 0
-+        [ -d "/lib/modules/$2/kernel" ] || exit 0
-         exec depmod -a "$2"
-         ;;
-     remove)
--        exec rm -f /lib/modules/"$2"/modules.{alias{,.bin},builtin.bin,dep{,.bin},devname,softdep,symbols{,.bin}}
-+        for d in alias \
-+            alias.bin \
-+            builtin.bin \
-+            dep \
-+            dep.bin \
-+            devname \
-+            softdep \
-+            symbols \
-+            symbols.bin
-+        do
-+            rm -f "/lib/modules/$2/modules.$d"
-+        done
-         ;;
-     *)
-         exit 0
--- 
-2.19.2
-
diff --git a/debian/patches/apertis/Add-usr-to-non-unmountable-list.patch b/debian/patches/apertis/Add-usr-to-non-unmountable-list.patch
index 6f25ee5b44a706a6bbb313c8e0e968b1a6d0ab7c..bed74c151ef770e0eef810101289a3947aa2d7de 100644
--- a/debian/patches/apertis/Add-usr-to-non-unmountable-list.patch
+++ b/debian/patches/apertis/Add-usr-to-non-unmountable-list.patch
@@ -1,4 +1,3 @@
-From 753dadfde295b15826a414757c664c6a760e979b Mon Sep 17 00:00:00 2001
 From: Denis Pynkin <denis.pynkin@collabora.com>
 Date: Wed, 10 Mar 2021 01:58:37 +0300
 Subject: [PATCH] Add /usr to non-unmountable list
@@ -20,14 +19,14 @@ unmounting it for Apertis images.
 
 Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
 ---
- src/core/umount.c | 2 --
+ src/shutdown/umount.c | 2 --
  1 file changed, 2 deletions(-)
 
-diff --git a/src/core/umount.c b/src/core/umount.c
-index 7af0195..26f4c11 100644
---- a/src/core/umount.c
-+++ b/src/core/umount.c
-@@ -382,9 +382,7 @@ static int delete_dm(dev_t devnum) {
+diff --git a/src/shutdown/umount.c b/src/shutdown/umount.c
+index 3a72a13..970c055 100644
+--- a/src/shutdown/umount.c
++++ b/src/shutdown/umount.c
+@@ -500,9 +500,7 @@ static int delete_md(MountPoint *m) {
  
  static bool nonunmountable_path(const char *path) {
          return path_equal(path, "/")
@@ -37,6 +36,3 @@ index 7af0195..26f4c11 100644
                  || path_startswith(path, "/run/initramfs");
  }
  
--- 
-2.25.4
-
diff --git a/debian/patches/apertis/Force-the-call-of-systemd-journal-flush-before-var-u.patch b/debian/patches/apertis/Force-the-call-of-systemd-journal-flush-before-var-u.patch
deleted file mode 100644
index 986abbd6d6171e097955c9a8e0561fbc44fcc498..0000000000000000000000000000000000000000
--- a/debian/patches/apertis/Force-the-call-of-systemd-journal-flush-before-var-u.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From f09e75bfb76f747e966b5ee9c5843a66177871dd Mon Sep 17 00:00:00 2001
-From: Denis Pynkin <denis.pynkin@collabora.com>
-Date: Tue, 17 Nov 2020 20:03:17 +0300
-Subject: [PATCH] Force the call of systemd-journal-flush before `/var` unmount
-
-The problem with failed `/var` unmount placed on separate partition
-have a long story: https://github.com/systemd/systemd/issues/867
-According messages after the fix integrated into upstream -- there are
-some corner cases which aren't fully fixed by patches adding [relinquish
-options](https://gitlab.apertis.org/pkg/systemd/-/merge_requests/26)
-
-In case of ostree-based images we have a similar issue since `/var` is
-bind-mounted in initramfs. Systemd is trying to unmount `/var` on
-shutdown, however `ExecStop=` command from `systemd-journal-flush`
-service is not executed during shutdown.
-By adding `PartOf=var.mount` into service file we force the
-`systemd-journal-flush.service` to be called prior the `/var` unmount.
-This allow to unlock the bind-mount, since `journald` have a chance to
-re-link it's journal into `/run` with `journalctl
---smart-relinquish-var` call.
-
-Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
----
- units/systemd-journal-flush.service.in | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/units/systemd-journal-flush.service.in b/units/systemd-journal-flush.service.in
-index bacfe51..c10eece 100644
---- a/units/systemd-journal-flush.service.in
-+++ b/units/systemd-journal-flush.service.in
-@@ -15,6 +15,7 @@ Requires=systemd-journald.service
- After=systemd-journald.service systemd-remount-fs.service
- Before=systemd-tmpfiles-setup.service
- RequiresMountsFor=/var/log/journal
-+PartOf=var.mount
- 
- [Service]
- ExecStart=@rootbindir@/journalctl --flush
--- 
-2.25.4
-
diff --git a/debian/patches/apertis/0002-Remove-bashisms-from-the-UEFI-entries-generator.patch b/debian/patches/apertis/Remove-bashisms-from-the-UEFI-entries-generator.patch
similarity index 63%
rename from debian/patches/apertis/0002-Remove-bashisms-from-the-UEFI-entries-generator.patch
rename to debian/patches/apertis/Remove-bashisms-from-the-UEFI-entries-generator.patch
index 2be4343c79caaaa8a4749203b37de77714a44b74..22e76906c6471abd0b6a9b9aec10bfee0935c197 100644
--- a/debian/patches/apertis/0002-Remove-bashisms-from-the-UEFI-entries-generator.patch
+++ b/debian/patches/apertis/Remove-bashisms-from-the-UEFI-entries-generator.patch
@@ -1,6 +1,6 @@
 From: Denis Pynkin <denis.pynkin@collabora.com>
 Date: Thu, 14 Feb 2019 00:04:13 +0300
-Subject: [PATCH 2/3] Remove bashisms from the UEFI entries generator
+Subject: Remove bashisms from the UEFI entries generator
 
 - Use [ not [[ and -n to test for non-emptiness
 - Use shell lists instead of arrays
@@ -8,60 +8,54 @@ Subject: [PATCH 2/3] Remove bashisms from the UEFI entries generator
 Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
 Signed-off-by: Frederic Dalleau <frederic.dalleau@collabora.com>
 ---
- src/kernel-install/90-loaderentry.install | 81 ++++++++++++++++++-------------
- 1 file changed, 47 insertions(+), 34 deletions(-)
+ src/kernel-install/90-loaderentry.install | 77 +++++++++++++++++--------------
+ 1 file changed, 43 insertions(+), 34 deletions(-)
 
 diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install
-index 75dd5a1..c7d0ac4 100644
+index d096745..9e1b910 100644
 --- a/src/kernel-install/90-loaderentry.install
 +++ b/src/kernel-install/90-loaderentry.install
 @@ -1,4 +1,4 @@
--#!/bin/bash
+-#!/usr/bin/env bash
 +#!/bin/sh
  # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
  # ex: ts=8 sw=4 sts=4 et filetype=sh
  
-@@ -6,68 +6,71 @@ COMMAND="$1"
+@@ -6,13 +6,13 @@ COMMAND="$1"
  KERNEL_VERSION="$2"
- BOOT_DIR_ABS="$3"
+ ENTRY_DIR_ABS="$3"
  KERNEL_IMAGE="$4"
 -INITRD_OPTIONS_START="5"
-+INITRD_OPTIONS_SHIFT="4"
++INITRD_OPTIONS_START="4"
  
 -if ! [[ $KERNEL_INSTALL_MACHINE_ID ]]; then
--    exit 0
-+if ! [ -n "$KERNEL_INSTALL_MACHINE_ID" ]; then
-+    if ! [ -f /etc/machine-id ]; then
-+        exit 0
-+    fi
-+    read KERNEL_INSTALL_MACHINE_ID </etc/machine-id
++if ! [ -n $KERNEL_INSTALL_MACHINE_ID ]; then
+     exit 0
  fi
  
--if ! [[ -d "$BOOT_DIR_ABS" ]]; then
-+if ! [ -d "$BOOT_DIR_ABS" ]; then
+-if ! [[ -d "$ENTRY_DIR_ABS" ]]; then
++if ! [ -d "$ENTRY_DIR_ABS" ]; then
      exit 0
  fi
  
- MACHINE_ID=$KERNEL_INSTALL_MACHINE_ID
- 
- BOOT_DIR="/$MACHINE_ID/$KERNEL_VERSION"
--BOOT_ROOT=${BOOT_DIR_ABS%$BOOT_DIR}
-+BOOT_ROOT="${BOOT_DIR_ABS%$BOOT_DIR}"
+@@ -22,48 +22,47 @@ BOOT_ROOT=${ENTRY_DIR_ABS%/$MACHINE_ID/$KERNEL_VERSION}
+ BOOT_MNT=$(stat -c %m $BOOT_ROOT)
+ ENTRY_DIR=${ENTRY_DIR_ABS#$BOOT_MNT}
  
 -if [[ $COMMAND == remove ]]; then
-+if [ "$COMMAND" = "remove" ]; then
++if [ $COMMAND = "remove" ]; then
      rm -f "$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION.conf"
      rm -f "$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION+"*".conf"
      exit 0
  fi
  
 -if ! [[ $COMMAND == add ]]; then
-+if ! [ "$COMMAND" = "add" ]; then
++if ! [ $COMMAND = "add" ]; then
      exit 1
  fi
  
 -if ! [[ $KERNEL_IMAGE ]]; then
-+if [ -z "$KERNEL_IMAGE" ]; then
++if ! [ -z "$KERNEL_IMAGE" ]; then
      exit 1
  fi
  
@@ -74,39 +68,35 @@ index 75dd5a1..c7d0ac4 100644
  fi
  
 -if ! [[ $PRETTY_NAME ]]; then
-+if [ -z "$PRETTY_NAME" ]; then
++if ! [ -z "$PRETTY_NAME" ]; then
      PRETTY_NAME="Linux $KERNEL_VERSION"
  fi
  
--declare -a BOOT_OPTIONS
--
 -if [[ -f /etc/kernel/cmdline ]]; then
 -    read -r -d '' -a BOOT_OPTIONS < /etc/kernel/cmdline
-+if [ -f /etc/kernel/cmdline ]; then
-+    read -r BOOT_OPTIONS < /etc/kernel/cmdline
- fi
- 
--if ! [[ ${BOOT_OPTIONS[*]} ]]; then
+-elif [[ -f /usr/lib/kernel/cmdline ]]; then
+-    read -r -d '' -a BOOT_OPTIONS < /usr/lib/kernel/cmdline
+-else
+-    declare -a BOOT_OPTIONS
+-
 -    read -r -d '' -a line < /proc/cmdline
 -    for i in "${line[@]}"; do
 -        [[ "${i#initrd=*}" != "$i" ]] && continue
+-        [[ "${i#BOOT_IMAGE=*}" != "$i" ]] && continue
 -        BOOT_OPTIONS+=("$i")
 -    done
-+if [ -z "${BOOT_OPTIONS}" ] && [ -f "/proc/cmdline" ]; then
++if [ -f /etc/kernel/cmdline ]; then
++    read -r BOOT_OPTIONS < /etc/kernel/cmdline
++elif [ -f /usr/lib/kernel/cmdline ]; then
++    read -r BOOT_OPTIONS < /usr/lib/kernel/cmdline
++elif [ -f "/proc/cmdline" ]; then
 +    BOOT_OPTIONS=$(
 +        cat /proc/cmdline | tr ' ' '\n' | \
 +        while read -r i; do
 +            [ "${i#initrd=*}" != "$i" ] && continue
 +            echo -n " $i"
 +        done
-+    )
- fi
- 
--if ! [[ ${BOOT_OPTIONS[*]} ]]; then
-+if [ -z "${BOOT_OPTIONS}" ]; then
-     echo "Could not determine the kernel command line parameters." >&2
-     echo "Please specify the kernel command line in /etc/kernel/cmdline!" >&2
-     exit 1
++     )
  fi
  
 -if [[ -f /etc/kernel/tries ]]; then
@@ -117,7 +107,7 @@ index 75dd5a1..c7d0ac4 100644
          echo "/etc/kernel/tries does not contain an integer." >&2
          exit 1
      fi
-@@ -83,11 +86,20 @@ cp "$KERNEL_IMAGE" "$BOOT_DIR_ABS/linux" &&
+@@ -79,11 +78,20 @@ cp "$KERNEL_IMAGE" "$ENTRY_DIR_ABS/linux" &&
      exit 1
  }
  
@@ -125,12 +115,12 @@ index 75dd5a1..c7d0ac4 100644
 +shift $INITRD_OPTIONS_SHIFT
 +INITRD_OPTIONS=""
 +while [ $# -gt 0 ] ; do
-+	if [ -z "$INITRD_OPTIONS" ] ; then
-+		INITRD_OPTIONS="$1"
-+	else
-+		INITRD_OPTIONS="$INITRD_OPTIONS\n$1"
-+	fi
-+	shift
++ if [ -z "$INITRD_OPTIONS" ] ; then
++   INITRD_OPTIONS="$1"
++ else
++   INITRD_OPTIONS="$INITRD_OPTIONS\n$1"
++ fi
++ shift
 +done
  
 -for initrd in "${INITRD_OPTIONS[@]}"; do
@@ -139,28 +129,28 @@ index 75dd5a1..c7d0ac4 100644
 +echo "${INITRD_OPTIONS}" | while read initrd; do
 +    if [ -f "${initrd}" ]; then
 +        initrd_basename=$(basename "${initrd}")
-         cp "${initrd}" "$BOOT_DIR_ABS/${initrd_basename}" &&
-             chown root:root "$BOOT_DIR_ABS/${initrd_basename}" &&
-             chmod 0644 "$BOOT_DIR_ABS/${initrd_basename}" || {
-@@ -99,7 +111,7 @@ done
+         [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
+             echo "Installing $ENTRY_DIR_ABS/${initrd_basename}"
+         cp "${initrd}" "$ENTRY_DIR_ABS/${initrd_basename}" &&
+@@ -97,7 +105,7 @@ done
  
- # If no initrd option is supplied, fallback to "initrd" which is
+ # If no initrd option is supplied, fall back to "initrd" which is
  # the name used by dracut when generating it in its kernel-install hook
 -[[ ${#INITRD_OPTIONS[@]} == 0 ]] && INITRD_OPTIONS=( initrd )
 +[ -z "${INITRD_OPTIONS}" ] && INITRD_OPTIONS=initrd
  
  mkdir -p "${LOADER_ENTRY%/*}" || {
      echo "Could not create loader entry directory '${LOADER_ENTRY%/*}'." >&2
-@@ -110,11 +122,12 @@ mkdir -p "${LOADER_ENTRY%/*}" || {
+@@ -110,11 +118,12 @@ mkdir -p "${LOADER_ENTRY%/*}" || {
      echo "title      $PRETTY_NAME"
      echo "version    $KERNEL_VERSION"
      echo "machine-id $MACHINE_ID"
 -    echo "options    ${BOOT_OPTIONS[*]}"
-+    echo "options    $BOOT_OPTIONS"
-     echo "linux      $BOOT_DIR/linux"
++    echo "options    ${BOOT_OPTIONS}"
+     echo "linux      $ENTRY_DIR/linux"
 -    for initrd in "${INITRD_OPTIONS[@]}"; do
--        [[ -f $BOOT_DIR_ABS/$(basename ${initrd}) ]] && \
--            echo "initrd     $BOOT_DIR/$(basename ${initrd})"
+-        [[ -f $ENTRY_DIR_ABS/$(basename ${initrd}) ]] && \
+-            echo "initrd     $ENTRY_DIR/$(basename ${initrd})"
 +    echo "${INITRD_OPTIONS}" | while read initrd; do
 +        initrd_basename=$(basename "${initrd}")
 +        [ -f "$BOOT_DIR_ABS/${initrd_basename}" ] && \
diff --git a/debian/patches/apertis/Remove-bashisms-from-the-depmod-wrapper.patch b/debian/patches/apertis/Remove-bashisms-from-the-depmod-wrapper.patch
new file mode 100644
index 0000000000000000000000000000000000000000..7827e531b8f089a43f622ca45c54fab143b36ab8
--- /dev/null
+++ b/debian/patches/apertis/Remove-bashisms-from-the-depmod-wrapper.patch
@@ -0,0 +1,60 @@
+From: Denis Pynkin <denis.pynkin@collabora.com>
+Date: Thu, 24 Jan 2019 22:40:46 +0300
+Subject: Remove bashisms from the depmod wrapper
+
+- Use [ not [[ and -n to test for non-emptiness
+- Use for loop instead of comma expansion
+
+Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
+[ Rebased to the latest master, amended the rm call ]
+Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk>
+---
+ src/kernel-install/50-depmod.install | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/src/kernel-install/50-depmod.install b/src/kernel-install/50-depmod.install
+index 3850eac..2b026da 100644
+--- a/src/kernel-install/50-depmod.install
++++ b/src/kernel-install/50-depmod.install
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env bash
++#!//bin/sh
+ # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+ # ex: ts=8 sw=4 sts=4 et filetype=sh
+ 
+@@ -8,11 +8,11 @@ ENTRY_DIR_ABS="$3"
+ KERNEL_IMAGE="$4"
+ INITRD_OPTIONS_START="5"
+ 
+-[[ $KERNEL_VERSION ]] || exit 1
++[ -n $KERNEL_VERSION ] || exit 1
+ 
+ case "$COMMAND" in
+     add)
+-        [[ -d "/lib/modules/${KERNEL_VERSION}/kernel" ]] || exit 0
++        [ -d "/lib/modules/${KERNEL_VERSION}/kernel" ] || exit 0
+         [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
+             echo "Running depmod -a ${KERNEL_VERSION}"
+         exec depmod -a "${KERNEL_VERSION}"
+@@ -20,8 +20,19 @@ case "$COMMAND" in
+     remove)
+         [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
+             echo "Removing /lib/modules/${KERNEL_VERSION}/modules.dep and associated files"
+-        exec rm -f /lib/modules/"${KERNEL_VERSION}"/modules.{alias{,.bin},builtin.bin,dep{,.bin},devname,softdep,symbols{,.bin}}
+-        ;;
++        for d in alias \
++             alias.bin \
++             builtin.bin \
++             dep \
++             dep.bin \
++             devname \
++             softdep \
++             symbols \
++             symbols.bin
++        do
++            rm -f "/lib/modules/$2/modules.$d"
++        done
++         ;;
+     *)
+         exit 0
+ esac
diff --git a/debian/patches/apertis/0003-Reworked-kernel-install-script.patch b/debian/patches/apertis/Reworked-kernel-install-script.patch
similarity index 59%
rename from debian/patches/apertis/0003-Reworked-kernel-install-script.patch
rename to debian/patches/apertis/Reworked-kernel-install-script.patch
index feec6869b32582e0fe055d28f9a4be58db491383..85309a9ff034362b9732704b92e4a08fe678aac2 100644
--- a/debian/patches/apertis/0003-Reworked-kernel-install-script.patch
+++ b/debian/patches/apertis/Reworked-kernel-install-script.patch
@@ -1,6 +1,6 @@
 From: Denis Pynkin <denis.pynkin@collabora.com>
 Date: Thu, 14 Feb 2019 00:46:48 +0300
-Subject: [PATCH 3/3] Reworked kernel-install script
+Subject: Reworked kernel-install script
 
 - Removed bashisms -- script is adapted for running with `/bin/sh`
 - Add support of calling the script without passing the kernel image.
@@ -13,23 +13,20 @@ Subject: [PATCH 3/3] Reworked kernel-install script
 Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
 Signed-off-by: Frederic Dalleau <frederic.dalleau@collabora.com>
 ---
- src/kernel-install/kernel-install | 100 ++++++++++++++++++++++----------------
- 1 file changed, 57 insertions(+), 43 deletions(-)
- mode change 100644 => 100755 src/kernel-install/kernel-install
+ src/kernel-install/kernel-install | 99 ++++++++++++++++++++++-----------------
+ 1 file changed, 56 insertions(+), 43 deletions(-)
 
 diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install
-old mode 100644
-new mode 100755
-index b85c7c5..3ca2071
+index e7457e9..edd6514 100755
 --- a/src/kernel-install/kernel-install
 +++ b/src/kernel-install/kernel-install
 @@ -1,4 +1,4 @@
--#!/bin/bash
+-#!/usr/bin/env bash
 +#!/bin/sh
  # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
  # ex: ts=8 sw=4 sts=4 et filetype=sh
- # SPDX-License-Identifier: LGPL-2.1+
-@@ -31,22 +31,18 @@ usage()
+ # SPDX-License-Identifier: LGPL-2.1-or-later
+@@ -33,22 +33,18 @@ usage()
  dropindirs_sort()
  {
      local suffix=$1; shift
@@ -61,23 +58,31 @@ index b85c7c5..3ca2071
                  echo "$d/$f"
                  continue 2
              fi
-@@ -57,42 +53,58 @@ dropindirs_sort()
+@@ -59,51 +55,65 @@ dropindirs_sort()
  export LC_COLLATE=C
  
  for i in "$@"; do
 -    if [ "$i" == "--help" -o "$i" == "-h" ]; then
-+    if [ "$i" = "--help" ] || [ "$i" = "-h" ]; then
++    if [ "$i" = "--help" -o "$i" = "-h" ]; then
          usage
          exit 0
      fi
  done
  
+ KERNEL_INSTALL_VERBOSE=0
+-if [ "$1" == "--verbose" -o "$1" == "-v" ]; then
++if [ "$1" = "--verbose" -o "$1" = "-v" ]; then
+     shift
+     KERNEL_INSTALL_VERBOSE=1
+ fi
+ export KERNEL_INSTALL_VERBOSE
+ 
 -if [[ "${0##*/}" == 'installkernel' ]]; then
 +INITRD_OPTIONS=""
 +if [ "${0%installkernel}" != "${0}" ]; then
      COMMAND='add'
--    # make install doesn't pass any parameter wrt initrd handling
--    INITRD_OPTIONS=()
+     # make install doesn't pass any parameter wrt initrd handling
+     INITRD_OPTIONS=()
 +    KERNEL_VERSION="$1"
 +    KERNEL_IMAGE="$2"
 +elif [ "${0%removekernel}" != "${0}" ]; then
@@ -86,26 +91,32 @@ index b85c7c5..3ca2071
 +    KERNEL_IMAGE="$2"
  else
      COMMAND="$1"
-+    KERNEL_VERSION="$2"
-+    KERNEL_IMAGE="$3"
++    KERNEL_VERSION="$1"
++    KERNEL_IMAGE="$2"
      shift
 -    INITRD_OPTIONS=( "${@:3}" )
 +    while [ $# -gt 2 ] ; do
-+	if [ -z "$INITRD_OPTIONS" ] ; then
-+		INITRD_OPTIONS="$3"
-+	else
-+		INITRD_OPTIONS="$INITRD_OPTIONS\n$3"
-+	fi
-+	shift
++        if [ -z "$INITRD_OPTIONS" ] ; then
++            INITRD_OPTIONS="$3"
++        else
++            INITRD_OPTIONS="$INITRD_OPTIONS\n$3"
++        fi
++        shift
 +    done
  fi
  
 -KERNEL_VERSION="$1"
 -KERNEL_IMAGE="$2"
--
--if [[ -f /etc/machine-id ]]; then
-+if [ -f /etc/machine-id ]; then
+ 
+ # Reuse directory created without a machine ID present if it exists.
+-if [[ -d /efi/Default ]] || [[ -d /boot/Default ]] || [[ -d /boot/efi/Default ]]; then
++if [ -d /efi/Default ] || [ -d /boot/Default ] || [ -d /boot/efi/Default ]; then
+     MACHINE_ID="Default"
+-elif [[ -f /etc/machine-id ]]; then
++elif [ -f /etc/machine-id ]; then
      read MACHINE_ID < /etc/machine-id
+ else
+     MACHINE_ID="Default"
  fi
  
 -if [[ ! $COMMAND ]] || [[ ! $KERNEL_VERSION ]]; then
@@ -114,27 +125,18 @@ index b85c7c5..3ca2071
      exit 1
  fi
  
--if ! [[ $MACHINE_ID ]]; then
-+# According to man page 2-nd parameter could be skipped
-+if [ -z "$KERNEL_IMAGE" ]; then
-+    KERNEL_IMAGE="/boot/vmlinuz-$KERNEL_VERSION"
-+fi
-+
-+if [ -z "$MACHINE_ID" ]; then
-     BOOT_DIR_ABS=$(mktemp -d /tmp/kernel-install.XXXXX) || exit 1
-     trap "rm -rf '$BOOT_DIR_ABS'" EXIT INT QUIT PIPE
--elif [[ -d /efi/loader/entries ]] || [[ -d /efi/$MACHINE_ID ]]; then
-+elif [ -d /efi/loader/entries ] || [ -d /efi/$MACHINE_ID ]; then
-     BOOT_DIR_ABS="/efi/$MACHINE_ID/$KERNEL_VERSION"
+-if [[ -d /efi/loader/entries ]] || [[ -d /efi/$MACHINE_ID ]]; then
++if [ -d /efi/loader/entries ] || [ -d /efi/$MACHINE_ID ]; then
+     ENTRY_DIR_ABS="/efi/$MACHINE_ID/$KERNEL_VERSION"
 -elif [[ -d /boot/loader/entries ]] || [[ -d /boot/$MACHINE_ID ]]; then
 +elif [ -d /boot/loader/entries ] || [ -d /boot/$MACHINE_ID ]; then
-     BOOT_DIR_ABS="/boot/$MACHINE_ID/$KERNEL_VERSION"
+     ENTRY_DIR_ABS="/boot/$MACHINE_ID/$KERNEL_VERSION"
 -elif [[ -d /boot/efi/loader/entries ]] || [[ -d /boot/efi/$MACHINE_ID ]]; then
 +elif [ -d /boot/efi/loader/entries ] || [ -d /boot/efi/$MACHINE_ID ]; then
-     BOOT_DIR_ABS="/boot/efi/$MACHINE_ID/$KERNEL_VERSION"
+     ENTRY_DIR_ABS="/boot/efi/$MACHINE_ID/$KERNEL_VERSION"
  elif mountpoint -q /efi; then
-     BOOT_DIR_ABS="/efi/$MACHINE_ID/$KERNEL_VERSION"
-@@ -106,15 +118,16 @@ export KERNEL_INSTALL_MACHINE_ID=$MACHINE_ID
+     ENTRY_DIR_ABS="/efi/$MACHINE_ID/$KERNEL_VERSION"
+@@ -117,51 +127,53 @@ export KERNEL_INSTALL_MACHINE_ID=$MACHINE_ID
  
  ret=0
  
@@ -150,20 +152,29 @@ index b85c7c5..3ca2071
  case $COMMAND in
      add)
 -        if [[ ! "$KERNEL_IMAGE" ]]; then
+-            echo "Command 'add' requires an argument" >&2
+-            exit 1
++        # According to man page 2-nd parameter could be skipped
 +        if [ -z "$KERNEL_IMAGE" ]; then
-             echo "Command 'add' requires an argument" >&2
-             exit 1
++            KERNEL_IMAGE="/boot/vmlinuz-$KERNEL_VERSION"
          fi
-@@ -124,42 +137,42 @@ case $COMMAND in
+ 
+-        if [[ ! -f "$KERNEL_IMAGE" ]]; then
++        if [ ! -f "$KERNEL_IMAGE" ]; then
+             echo "Kernel image argument ${KERNEL_IMAGE} not a file" >&2
              exit 1
-         }
+         fi
  
 -        for f in "${PLUGINS[@]}"; do
 -            if [[ -x $f ]]; then
--                "$f" add "$KERNEL_VERSION" "$BOOT_DIR_ABS" "$KERNEL_IMAGE" "${INITRD_OPTIONS[@]}"
 +        plugins_list | while read f; do
 +            if [ -x "$f" ]; then
-+                "$f" add "$KERNEL_VERSION" "$BOOT_DIR_ABS" "$KERNEL_IMAGE" "${INITRD_OPTIONS}"
++
+                 [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
+-                    echo "+$f add $KERNEL_VERSION $ENTRY_DIR_ABS $KERNEL_IMAGE ${INITRD_OPTIONS[@]}"
+-                "$f" add "$KERNEL_VERSION" "$ENTRY_DIR_ABS" "$KERNEL_IMAGE" "${INITRD_OPTIONS[@]}"
++                    echo "+$f add $KERNEL_VERSION $ENTRY_DIR_ABS $KERNEL_IMAGE ${INITRD_OPTIONS}"
++                "$f" add "$KERNEL_VERSION" "$ENTRY_DIR_ABS" "$KERNEL_IMAGE" "${INITRD_OPTIONS}"
                  x=$?
 -                if [[ $x == $SKIP_REMAINING ]]; then
 +                if [ $x = $SKIP_REMAINING ]; then
@@ -171,19 +182,9 @@ index b85c7c5..3ca2071
                      break
                  fi
 -                ((ret+=$x))
-+                ret=`expr $ret + $x`
++                ret=`expr $ret + $?
              fi
          done
- 
--        if ! [[ $MACHINE_ID ]] && ! rmdir "$BOOT_DIR_ABS"; then
-+        if [ -z "$MACHINE_ID" ] && ! rmdir "$BOOT_DIR_ABS"; then
-             echo "Warning: In kernel-install plugins, requiring BOOT_DIR_ABS to be preset is deprecated." >&2
-             echo "         All plugins should not put anything in BOOT_DIR_ABS if the environment" >&2
-             echo "         variable KERNEL_INSTALL_MACHINE_ID is empty." >&2
-             rm -rf "$BOOT_DIR_ABS"
--            ((ret+=$?))
-+            ret=`expr $ret + $?`
-         fi
          ;;
  
      remove)
@@ -191,7 +192,9 @@ index b85c7c5..3ca2071
 -            if [[ -x $f ]]; then
 +        plugins_list | while read f; do
 +            if [ -x "$f" ]; then
-                 "$f" remove "$KERNEL_VERSION" "$BOOT_DIR_ABS"
+                 [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \
+                     echo "+$f remove $KERNEL_VERSION $ENTRY_DIR_ABS"
+                 "$f" remove "$KERNEL_VERSION" "$ENTRY_DIR_ABS"
                  x=$?
 -                if [[ $x == $SKIP_REMAINING ]]; then
 +                if [ $x = $SKIP_REMAINING ]; then
@@ -203,13 +206,16 @@ index b85c7c5..3ca2071
              fi
          done
  
-         rm -rf "$BOOT_DIR_ABS"
+@@ -169,7 +181,7 @@ case $COMMAND in
+             echo "Removing $ENTRY_DIR_ABS"
+ 
+         rm -rf "$ENTRY_DIR_ABS"
 -        ((ret+=$?))
 +        ret=`expr $ret + $?`
          ;;
  
      *)
-@@ -169,3 +182,4 @@ case $COMMAND in
+@@ -179,3 +191,4 @@ case $COMMAND in
  esac
  
  exit $ret
diff --git a/debian/patches/apertis/fuzzer-add-varlink-fuzzer.patch b/debian/patches/apertis/fuzzer-add-varlink-fuzzer.patch
deleted file mode 100644
index f5e3ab8b0c4461e721acc08388da45d2e8fdc804..0000000000000000000000000000000000000000
Binary files a/debian/patches/apertis/fuzzer-add-varlink-fuzzer.patch and /dev/null differ
diff --git a/debian/patches/apertis/journalctl-add-new-relinquish-and-smart-relinquish-option.patch b/debian/patches/apertis/journalctl-add-new-relinquish-and-smart-relinquish-option.patch
deleted file mode 100644
index 14e45074e2e061b4a5fac439e9d081c804ceb9b1..0000000000000000000000000000000000000000
--- a/debian/patches/apertis/journalctl-add-new-relinquish-and-smart-relinquish-option.patch
+++ /dev/null
@@ -1,236 +0,0 @@
-From: Lennart Poettering <lennart@poettering.net>
-Date: Fri, 5 Apr 2019 18:21:02 +0200
-Subject: journalctl: add new --relinquish and --smart-relinquish options
-
-The latter is identical to the former, but becomes a NOP if
-/var/log/journal is on the same mount as /, and thus during shutdown
-unmounting /var is not necessary and hence we can keep logging until the
-very end.
-
-Signed-off-by: Martyn Welch <martyn.welch@collabora.com>
-[Martyn Welch: Backported to systemd v241]
----
- src/journal/journalctl.c | 161 ++++++++++++++++++++++++++++++-----------------
- 1 file changed, 103 insertions(+), 58 deletions(-)
-
-diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
-index 910aced..5bde51d 100644
---- a/src/journal/journalctl.c
-+++ b/src/journal/journalctl.c
-@@ -51,6 +51,7 @@
- #include "log.h"
- #include "logs-show.h"
- #include "mkdir.h"
-+#include "mountpoint-util.h"
- #include "pager.h"
- #include "parse-util.h"
- #include "path-util.h"
-@@ -165,6 +166,7 @@ static enum {
-         ACTION_UPDATE_CATALOG,
-         ACTION_LIST_BOOTS,
-         ACTION_FLUSH,
-+        ACTION_RELINQUISH_VAR,
-         ACTION_SYNC,
-         ACTION_ROTATE,
-         ACTION_VACUUM,
-@@ -361,6 +363,8 @@ static int help(void) {
-                "     --vacuum-time=TIME      Remove journal files older than specified time\n"
-                "     --verify                Verify journal file consistency\n"
-                "     --sync                  Synchronize unwritten journal messages to disk\n"
-+               "     --relinquish-var        Stop logging to disk, log to temporary file system\n"
-+               "     --smart-relinquish-var  Similar, but NOP if log directory is on root mount\n"
-                "     --flush                 Flush all journal data from /run into /var\n"
-                "     --rotate                Request immediate rotation of the journal files\n"
-                "     --header                Show journal header information\n"
-@@ -407,6 +411,8 @@ static int parse_argv(int argc, char *argv[]) {
-                 ARG_UTC,
-                 ARG_SYNC,
-                 ARG_FLUSH,
-+                ARG_RELINQUISH_VAR,
-+                ARG_SMART_RELINQUISH_VAR,
-                 ARG_ROTATE,
-                 ARG_VACUUM_SIZE,
-                 ARG_VACUUM_FILES,
-@@ -416,64 +422,66 @@ static int parse_argv(int argc, char *argv[]) {
-         };
- 
-         static const struct option options[] = {
--                { "help",           no_argument,       NULL, 'h'                },
--                { "version" ,       no_argument,       NULL, ARG_VERSION        },
--                { "no-pager",       no_argument,       NULL, ARG_NO_PAGER       },
--                { "pager-end",      no_argument,       NULL, 'e'                },
--                { "follow",         no_argument,       NULL, 'f'                },
--                { "force",          no_argument,       NULL, ARG_FORCE          },
--                { "output",         required_argument, NULL, 'o'                },
--                { "all",            no_argument,       NULL, 'a'                },
--                { "full",           no_argument,       NULL, 'l'                },
--                { "no-full",        no_argument,       NULL, ARG_NO_FULL        },
--                { "lines",          optional_argument, NULL, 'n'                },
--                { "no-tail",        no_argument,       NULL, ARG_NO_TAIL        },
--                { "new-id128",      no_argument,       NULL, ARG_NEW_ID128      }, /* deprecated */
--                { "quiet",          no_argument,       NULL, 'q'                },
--                { "merge",          no_argument,       NULL, 'm'                },
--                { "this-boot",      no_argument,       NULL, ARG_THIS_BOOT      }, /* deprecated */
--                { "boot",           optional_argument, NULL, 'b'                },
--                { "list-boots",     no_argument,       NULL, ARG_LIST_BOOTS     },
--                { "dmesg",          no_argument,       NULL, 'k'                },
--                { "system",         no_argument,       NULL, ARG_SYSTEM         },
--                { "user",           no_argument,       NULL, ARG_USER           },
--                { "directory",      required_argument, NULL, 'D'                },
--                { "file",           required_argument, NULL, ARG_FILE           },
--                { "root",           required_argument, NULL, ARG_ROOT           },
--                { "header",         no_argument,       NULL, ARG_HEADER         },
--                { "identifier",     required_argument, NULL, 't'                },
--                { "priority",       required_argument, NULL, 'p'                },
--                { "grep",           required_argument, NULL, 'g'                },
--                { "case-sensitive", optional_argument, NULL, ARG_CASE_SENSITIVE },
--                { "setup-keys",     no_argument,       NULL, ARG_SETUP_KEYS     },
--                { "interval",       required_argument, NULL, ARG_INTERVAL       },
--                { "verify",         no_argument,       NULL, ARG_VERIFY         },
--                { "verify-key",     required_argument, NULL, ARG_VERIFY_KEY     },
--                { "disk-usage",     no_argument,       NULL, ARG_DISK_USAGE     },
--                { "cursor",         required_argument, NULL, 'c'                },
--                { "after-cursor",   required_argument, NULL, ARG_AFTER_CURSOR   },
--                { "show-cursor",    no_argument,       NULL, ARG_SHOW_CURSOR    },
--                { "since",          required_argument, NULL, 'S'                },
--                { "until",          required_argument, NULL, 'U'                },
--                { "unit",           required_argument, NULL, 'u'                },
--                { "user-unit",      required_argument, NULL, ARG_USER_UNIT      },
--                { "field",          required_argument, NULL, 'F'                },
--                { "fields",         no_argument,       NULL, 'N'                },
--                { "catalog",        no_argument,       NULL, 'x'                },
--                { "list-catalog",   no_argument,       NULL, ARG_LIST_CATALOG   },
--                { "dump-catalog",   no_argument,       NULL, ARG_DUMP_CATALOG   },
--                { "update-catalog", no_argument,       NULL, ARG_UPDATE_CATALOG },
--                { "reverse",        no_argument,       NULL, 'r'                },
--                { "machine",        required_argument, NULL, 'M'                },
--                { "utc",            no_argument,       NULL, ARG_UTC            },
--                { "flush",          no_argument,       NULL, ARG_FLUSH          },
--                { "sync",           no_argument,       NULL, ARG_SYNC           },
--                { "rotate",         no_argument,       NULL, ARG_ROTATE         },
--                { "vacuum-size",    required_argument, NULL, ARG_VACUUM_SIZE    },
--                { "vacuum-files",   required_argument, NULL, ARG_VACUUM_FILES   },
--                { "vacuum-time",    required_argument, NULL, ARG_VACUUM_TIME    },
--                { "no-hostname",    no_argument,       NULL, ARG_NO_HOSTNAME    },
--                { "output-fields",  required_argument, NULL, ARG_OUTPUT_FIELDS  },
-+                { "help",                 no_argument,       NULL, 'h'                      },
-+                { "version" ,             no_argument,       NULL, ARG_VERSION              },
-+                { "no-pager",             no_argument,       NULL, ARG_NO_PAGER             },
-+                { "pager-end",            no_argument,       NULL, 'e'                      },
-+                { "follow",               no_argument,       NULL, 'f'                      },
-+                { "force",                no_argument,       NULL, ARG_FORCE                },
-+                { "output",               required_argument, NULL, 'o'                      },
-+                { "all",                  no_argument,       NULL, 'a'                      },
-+                { "full",                 no_argument,       NULL, 'l'                      },
-+                { "no-full",              no_argument,       NULL, ARG_NO_FULL              },
-+                { "lines",                optional_argument, NULL, 'n'                      },
-+                { "no-tail",              no_argument,       NULL, ARG_NO_TAIL              },
-+                { "new-id128",            no_argument,       NULL, ARG_NEW_ID128            }, /* deprecated */
-+                { "quiet",                no_argument,       NULL, 'q'                      },
-+                { "merge",                no_argument,       NULL, 'm'                      },
-+                { "this-boot",            no_argument,       NULL, ARG_THIS_BOOT            }, /* deprecated */
-+                { "boot",                 optional_argument, NULL, 'b'                      },
-+                { "list-boots",           no_argument,       NULL, ARG_LIST_BOOTS           },
-+                { "dmesg",                no_argument,       NULL, 'k'                      },
-+                { "system",               no_argument,       NULL, ARG_SYSTEM               },
-+                { "user",                 no_argument,       NULL, ARG_USER                 },
-+                { "directory",            required_argument, NULL, 'D'                      },
-+                { "file",                 required_argument, NULL, ARG_FILE                 },
-+                { "root",                 required_argument, NULL, ARG_ROOT                 },
-+                { "header",               no_argument,       NULL, ARG_HEADER               },
-+                { "identifier",           required_argument, NULL, 't'                      },
-+                { "priority",             required_argument, NULL, 'p'                      },
-+                { "grep",                 required_argument, NULL, 'g'                      },
-+                { "case-sensitive",       optional_argument, NULL, ARG_CASE_SENSITIVE       },
-+                { "setup-keys",           no_argument,       NULL, ARG_SETUP_KEYS           },
-+                { "interval",             required_argument, NULL, ARG_INTERVAL             },
-+                { "verify",               no_argument,       NULL, ARG_VERIFY               },
-+                { "verify-key",           required_argument, NULL, ARG_VERIFY_KEY           },
-+                { "disk-usage",           no_argument,       NULL, ARG_DISK_USAGE           },
-+                { "cursor",               required_argument, NULL, 'c'                      },
-+                { "after-cursor",         required_argument, NULL, ARG_AFTER_CURSOR         },
-+                { "show-cursor",          no_argument,       NULL, ARG_SHOW_CURSOR          },
-+                { "since",                required_argument, NULL, 'S'                      },
-+                { "until",                required_argument, NULL, 'U'                      },
-+                { "unit",                 required_argument, NULL, 'u'                      },
-+                { "user-unit",            required_argument, NULL, ARG_USER_UNIT            },
-+                { "field",                required_argument, NULL, 'F'                      },
-+                { "fields",               no_argument,       NULL, 'N'                      },
-+                { "catalog",              no_argument,       NULL, 'x'                      },
-+                { "list-catalog",         no_argument,       NULL, ARG_LIST_CATALOG         },
-+                { "dump-catalog",         no_argument,       NULL, ARG_DUMP_CATALOG         },
-+                { "update-catalog",       no_argument,       NULL, ARG_UPDATE_CATALOG       },
-+                { "reverse",              no_argument,       NULL, 'r'                      },
-+                { "machine",              required_argument, NULL, 'M'                      },
-+                { "utc",                  no_argument,       NULL, ARG_UTC                  },
-+                { "flush",                no_argument,       NULL, ARG_FLUSH                },
-+                { "relinquish-var",       no_argument,       NULL, ARG_RELINQUISH_VAR       },
-+                { "smart-relinquish-var", no_argument,       NULL, ARG_SMART_RELINQUISH_VAR },
-+                { "sync",                 no_argument,       NULL, ARG_SYNC                 },
-+                { "rotate",               no_argument,       NULL, ARG_ROTATE               },
-+                { "vacuum-size",          required_argument, NULL, ARG_VACUUM_SIZE          },
-+                { "vacuum-files",         required_argument, NULL, ARG_VACUUM_FILES         },
-+                { "vacuum-time",          required_argument, NULL, ARG_VACUUM_TIME          },
-+                { "no-hostname",          no_argument,       NULL, ARG_NO_HOSTNAME          },
-+                { "output-fields",        required_argument, NULL, ARG_OUTPUT_FIELDS        },
-                 {}
-         };
- 
-@@ -897,6 +905,35 @@ static int parse_argv(int argc, char *argv[]) {
-                         arg_action = ACTION_FLUSH;
-                         break;
- 
-+                case ARG_SMART_RELINQUISH_VAR: {
-+                        int root_mnt_id, log_mnt_id;
-+
-+                        /* Try to be smart about relinquishing access to /var/log/journal/ during shutdown:
-+                         * if it's on the same mount as the root file system there's no point in
-+                         * relinquishing access and we can leave journald write to it until the very last
-+                         * moment. */
-+
-+                        r = path_get_mnt_id("/", &root_mnt_id);
-+                        if (r < 0)
-+                                log_debug_errno(r, "Failed to get root mount ID, ignoring: %m");
-+                        else {
-+                                r = path_get_mnt_id("/var/log/journal/", &log_mnt_id);
-+                                if (r < 0)
-+                                        log_debug_errno(r, "Failed to get journal directory mount ID, ignoring: %m");
-+                                else if (root_mnt_id == log_mnt_id) {
-+                                        log_debug("/var/log/journal/ is on root file system, not relinquishing access to /var.");
-+                                        return 0;
-+                                } else
-+                                        log_debug("/var/log/journal/ is not on the root file system, relinquishing access to it.");
-+                        }
-+
-+                        _fallthrough_;
-+                }
-+
-+                case ARG_RELINQUISH_VAR:
-+                        arg_action = ACTION_RELINQUISH_VAR;
-+                        break;
-+
-                 case ARG_ROTATE:
-                         arg_action = arg_action == ACTION_VACUUM ? ACTION_ROTATE_AND_VACUUM : ACTION_ROTATE;
-                         break;
-@@ -1907,6 +1944,10 @@ static int flush_to_var(void) {
-         return simple_varlink_call("--flush", "io.systemd.Journal.FlushToVar");
- }
- 
-+static int relinquish_var(void) {
-+        return simple_varlink_call("--relinquish-var", "io.systemd.Journal.RelinquishVar");
-+}
-+
- static int rotate(void) {
-         return simple_varlink_call("--rotate", "io.systemd.Journal.Rotate");
- }
-@@ -2020,6 +2061,10 @@ int main(int argc, char *argv[]) {
-                 r = flush_to_var();
-                 goto finish;
- 
-+        case ACTION_RELINQUISH_VAR:
-+                r = relinquish_var();
-+                goto finish;
-+
-         case ACTION_SYNC:
-                 r = sync_journal();
-                 goto finish;
diff --git a/debian/patches/apertis/journalctl-port-flush-sync-rotate-to-use-varlink-method-c.patch b/debian/patches/apertis/journalctl-port-flush-sync-rotate-to-use-varlink-method-c.patch
deleted file mode 100644
index fd22f1a65fe2057b6f04ba9987072262b2fe0278..0000000000000000000000000000000000000000
--- a/debian/patches/apertis/journalctl-port-flush-sync-rotate-to-use-varlink-method-c.patch
+++ /dev/null
@@ -1,273 +0,0 @@
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 4 Apr 2019 19:41:33 +0200
-Subject: journalctl: port --flush/--sync/--rotate to use varlink method calls
-
-Signed-off-by: Martyn Welch <martyn.welch@collabora.com>
-[Martyn Welch: Backported to systemd v241]
----
- src/journal/journalctl.c      | 149 ++++--------------------------------------
- src/journal/journald-server.c |  58 +++++++++++++++-
- 2 files changed, 70 insertions(+), 137 deletions(-)
-
-diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
-index 14a02ed..910aced 100644
---- a/src/journal/journalctl.c
-+++ b/src/journal/journalctl.c
-@@ -65,6 +65,7 @@
- #include "tmpfile-util.h"
- #include "unit-name.h"
- #include "user-util.h"
-+#include "varlink.h"
- 
- #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
- 
-@@ -1883,157 +1884,35 @@ static int verify(sd_journal *j) {
-         return r;
- }
- 
--static int flush_to_var(void) {
--        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
--        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
--        _cleanup_close_ int watch_fd = -1;
-+static int simple_varlink_call(const char *option, const char *method) {
-+        _cleanup_(varlink_flush_close_unrefp) Varlink *link = NULL;
-+        const char *error;
-         int r;
- 
--        if (arg_machine) {
--                log_error("--flush is not supported in conjunction with --machine=.");
--                return -EOPNOTSUPP;
--        }
--
--        /* Quick exit */
--        if (access("/run/systemd/journal/flushed", F_OK) >= 0)
--                return 0;
-+        if (arg_machine)
-+                return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "%s is not supported in conjunction with --machine=.", option);
- 
--        /* OK, let's actually do the full logic, send SIGUSR1 to the
--         * daemon and set up inotify to wait for the flushed file to appear */
--        r = bus_connect_system_systemd(&bus);
--        if (r < 0)
--                return log_error_errno(r, "Failed to get D-Bus connection: %m");
--
--        r = sd_bus_call_method(
--                        bus,
--                        "org.freedesktop.systemd1",
--                        "/org/freedesktop/systemd1",
--                        "org.freedesktop.systemd1.Manager",
--                        "KillUnit",
--                        &error,
--                        NULL,
--                        "ssi", "systemd-journald.service", "main", SIGUSR1);
-+        r = varlink_connect_address(&link, "/run/systemd/journal/io.systemd.journal");
-         if (r < 0)
--                return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r));
--
--        mkdir_p("/run/systemd/journal", 0755);
-+                return log_error_errno(r, "Failed to connect to journal: %m");
- 
--        watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
--        if (watch_fd < 0)
--                return log_error_errno(errno, "Failed to create inotify watch: %m");
--
--        r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE|IN_DONT_FOLLOW|IN_ONLYDIR);
-+        r = varlink_call(link, method, NULL, NULL, &error, NULL);
-         if (r < 0)
--                return log_error_errno(errno, "Failed to watch journal directory: %m");
--
--        for (;;) {
--                if (access("/run/systemd/journal/flushed", F_OK) >= 0)
--                        break;
--
--                if (errno != ENOENT)
--                        return log_error_errno(errno, "Failed to check for existence of /run/systemd/journal/flushed: %m");
--
--                r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
--                if (r < 0)
--                        return log_error_errno(r, "Failed to wait for event: %m");
--
--                r = flush_fd(watch_fd);
--                if (r < 0)
--                        return log_error_errno(r, "Failed to flush inotify events: %m");
--        }
-+                return log_error_errno(r, "Failed to execute operation: %s", error);
- 
-         return 0;
- }
- 
--static int send_signal_and_wait(int sig, const char *watch_path) {
--        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
--        _cleanup_close_ int watch_fd = -1;
--        usec_t start;
--        int r;
--
--        if (arg_machine) {
--                log_error("--sync and --rotate are not supported in conjunction with --machine=.");
--                return -EOPNOTSUPP;
--        }
--
--        start = now(CLOCK_MONOTONIC);
--
--        /* This call sends the specified signal to journald, and waits
--         * for acknowledgment by watching the mtime of the specified
--         * flag file. This is used to trigger syncing or rotation and
--         * then wait for the operation to complete. */
--
--        for (;;) {
--                usec_t tstamp;
--
--                /* See if a sync happened by now. */
--                r = read_timestamp_file(watch_path, &tstamp);
--                if (r < 0 && r != -ENOENT)
--                        return log_error_errno(r, "Failed to read %s: %m", watch_path);
--                if (r >= 0 && tstamp >= start)
--                        return 0;
--
--                /* Let's ask for a sync, but only once. */
--                if (!bus) {
--                        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
--
--                        r = bus_connect_system_systemd(&bus);
--                        if (r < 0)
--                                return log_error_errno(r, "Failed to get D-Bus connection: %m");
--
--                        r = sd_bus_call_method(
--                                        bus,
--                                        "org.freedesktop.systemd1",
--                                        "/org/freedesktop/systemd1",
--                                        "org.freedesktop.systemd1.Manager",
--                                        "KillUnit",
--                                        &error,
--                                        NULL,
--                                        "ssi", "systemd-journald.service", "main", sig);
--                        if (r < 0)
--                                return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r));
--
--                        continue;
--                }
--
--                /* Let's install the inotify watch, if we didn't do that yet. */
--                if (watch_fd < 0) {
--
--                        mkdir_p("/run/systemd/journal", 0755);
--
--                        watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
--                        if (watch_fd < 0)
--                                return log_error_errno(errno, "Failed to create inotify watch: %m");
--
--                        r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_MOVED_TO|IN_DONT_FOLLOW|IN_ONLYDIR);
--                        if (r < 0)
--                                return log_error_errno(errno, "Failed to watch journal directory: %m");
--
--                        /* Recheck the flag file immediately, so that we don't miss any event since the last check. */
--                        continue;
--                }
--
--                /* OK, all preparatory steps done, let's wait until
--                 * inotify reports an event. */
--
--                r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
--                if (r < 0)
--                        return log_error_errno(r, "Failed to wait for event: %m");
--
--                r = flush_fd(watch_fd);
--                if (r < 0)
--                        return log_error_errno(r, "Failed to flush inotify events: %m");
--        }
--
--        return 0;
-+static int flush_to_var(void) {
-+        return simple_varlink_call("--flush", "io.systemd.Journal.FlushToVar");
- }
- 
- static int rotate(void) {
--        return send_signal_and_wait(SIGUSR2, "/run/systemd/journal/rotated");
-+        return simple_varlink_call("--rotate", "io.systemd.Journal.Rotate");
- }
- 
- static int sync_journal(void) {
--        return send_signal_and_wait(SIGRTMIN+1, "/run/systemd/journal/synced");
-+        return simple_varlink_call("--sync", "io.systemd.Journal.Synchronize");
- }
- 
- static int wait_for_change(sd_journal *j, int poll_fd) {
-diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
-index dc4b259..2aad8e9 100644
---- a/src/journal/journald-server.c
-+++ b/src/journal/journald-server.c
-@@ -1835,8 +1835,37 @@ static int server_connect_notify(Server *s) {
-         return 0;
- }
- 
-+static int synchronize_second_half(sd_event_source *event_source, void *userdata) {
-+        Varlink *link = userdata;
-+        Server *s;
-+        int r;
-+
-+        assert(link);
-+        assert_se(s = varlink_get_userdata(link));
-+
-+        /* This is the "second half" of the Synchronize() varlink method. This function is called as deferred
-+         * event source at a low priority to ensure the synchronization completes after all queued log
-+         * messages are processed. */
-+        server_full_sync(s);
-+
-+        /* Let's get rid of the event source now, by marking it as non-floating again. It then has no ref
-+         * anymore and is immediately destroyed after we return from this function, i.e. from this event
-+         * source handler at the end. */
-+        r = sd_event_source_set_floating(event_source, false);
-+        if (r < 0)
-+                return log_error_errno(r, "Failed to mark event source as non-floating: %m");
-+
-+        return varlink_reply(link, NULL);
-+}
-+
-+static void synchronize_destroy(void *userdata) {
-+        varlink_unref(userdata);
-+}
-+
- static int vl_method_synchronize(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
-+        _cleanup_(sd_event_source_unrefp) sd_event_source *event_source = NULL;
-         Server *s = userdata;
-+        int r;
- 
-         assert(link);
-         assert(s);
-@@ -1845,9 +1874,34 @@ static int vl_method_synchronize(Varlink *link, JsonVariant *parameters, Varlink
-                 return varlink_error_invalid_parameter(link, parameters);
- 
-         log_info("Received client request to rotate journal.");
--        server_full_sync(s);
- 
--        return varlink_reply(link, NULL);
-+        /* We don't do the main work now, but instead enqueue a deferred event loop job which will do
-+         * it. That job is scheduled at low priority, so that we return from this method call only after all
-+         * queued but not processed log messages are written to disk, so that this method call returning can
-+         * be used as nice synchronization point. */
-+        r = sd_event_add_defer(s->event, &event_source, synchronize_second_half, link);
-+        if (r < 0)
-+                return log_error_errno(r, "Failed to allocate defer event source: %m");
-+
-+        r = sd_event_source_set_destroy_callback(event_source, synchronize_destroy);
-+        if (r < 0)
-+                return log_error_errno(r, "Failed to set event source destroy callback: %m");
-+
-+        varlink_ref(link); /* The varlink object is now left to the destroy callack to unref */
-+
-+        r = sd_event_source_set_priority(event_source, SD_EVENT_PRIORITY_NORMAL+15);
-+        if (r < 0)
-+                return log_error_errno(r, "Failed to set defer event source priority: %m");
-+
-+        /* Give up ownership of this event source. It will now be destroyed along with event loop itself,
-+         * unless it destroys itself earlier. */
-+        r = sd_event_source_set_floating(event_source, true);
-+        if (r < 0)
-+                return log_error_errno(r, "Failed to mark event source as floating: %m");
-+
-+        (void) sd_event_source_set_description(event_source, "deferred-sync");
-+
-+        return 0;
- }
- 
- static int vl_method_rotate(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
diff --git a/debian/patches/apertis/journald-add-API-to-move-logging-from-var-to-run-again.patch b/debian/patches/apertis/journald-add-API-to-move-logging-from-var-to-run-again.patch
deleted file mode 100644
index a3ec8a88149506c0685cd0683b3b3077e1b93474..0000000000000000000000000000000000000000
--- a/debian/patches/apertis/journald-add-API-to-move-logging-from-var-to-run-again.patch
+++ /dev/null
@@ -1,197 +0,0 @@
-From: Lennart Poettering <lennart@poettering.net>
-Date: Fri, 5 Apr 2019 18:20:25 +0200
-Subject: journald: add API to move logging from /var to /run again
-
-We now have this nice little Varlink API, let's beef it up a bit.
-
-Signed-off-by: Martyn Welch <martyn.welch@collabora.com>
-[Martyn Welch: Backported to systemd v241]
----
- src/journal/journald-server.c | 76 ++++++++++++++++++++++++++++++++-----------
- 1 file changed, 57 insertions(+), 19 deletions(-)
-
-diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
-index 2aad8e9..77eecee 100644
---- a/src/journal/journald-server.c
-+++ b/src/journal/journald-server.c
-@@ -286,13 +286,14 @@ static bool flushed_flag_is_set(void) {
-         return access("/run/systemd/journal/flushed", F_OK) >= 0;
- }
- 
--static int system_journal_open(Server *s, bool flush_requested) {
-+static int system_journal_open(Server *s, bool flush_requested, bool relinquish_requested) {
-         const char *fn;
-         int r = 0;
- 
-         if (!s->system_journal &&
-             IN_SET(s->storage, STORAGE_PERSISTENT, STORAGE_AUTO) &&
--            (flush_requested || flushed_flag_is_set())) {
-+            (flush_requested || flushed_flag_is_set()) &&
-+            !relinquish_requested) {
- 
-                 /* If in auto mode: first try to create the machine
-                  * path, but not the prefix.
-@@ -334,7 +335,7 @@ static int system_journal_open(Server *s, bool flush_requested) {
- 
-                 fn = strjoina(s->runtime_storage.path, "/system.journal");
- 
--                if (s->system_journal) {
-+                if (s->system_journal && !relinquish_requested) {
- 
-                         /* Try to open the runtime journal, but only
-                          * if it already exists, so that we can flush
-@@ -389,7 +390,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
-          * else that's left the journals as NULL).
-          *
-          * Fixes https://github.com/systemd/systemd/issues/3968 */
--        (void) system_journal_open(s, false);
-+        (void) system_journal_open(s, false, false);
- 
-         /* We split up user logs only on /var, not on /run. If the
-          * runtime file is open, we write to it exclusively, in order
-@@ -1117,7 +1118,7 @@ int server_flush_to_var(Server *s, bool require_flag_file) {
-         char ts[FORMAT_TIMESPAN_MAX];
-         usec_t start;
-         unsigned n = 0;
--        int r;
-+        int r, k;
- 
-         assert(s);
- 
-@@ -1130,7 +1131,7 @@ int server_flush_to_var(Server *s, bool require_flag_file) {
-         if (require_flag_file && !flushed_flag_is_set())
-                 return 0;
- 
--        (void) system_journal_open(s, true);
-+        (void) system_journal_open(s, true, false);
- 
-         if (!s->system_journal)
-                 return 0;
-@@ -1209,9 +1210,36 @@ finish:
-                                           n),
-                               NULL);
- 
-+        k = touch("/run/systemd/journal/flushed");
-+        if (k < 0)
-+                log_warning_errno(k, "Failed to touch /run/systemd/journal/flushed, ignoring: %m");
-+
-         return r;
- }
- 
-+static int server_relinquish_var(Server *s) {
-+        assert(s);
-+
-+        if (s->storage == STORAGE_NONE)
-+                return 0;
-+
-+        if (s->runtime_journal && !s->system_journal)
-+                return 0;
-+
-+        log_debug("Relinquishing /var...");
-+
-+        (void) system_journal_open(s, false, true);
-+
-+        s->system_journal = journal_file_close(s->system_journal);
-+        ordered_hashmap_clear_with_destructor(s->user_journals, journal_file_close);
-+        set_clear_with_destructor(s->deferred_closes, journal_file_close);
-+
-+        if (unlink("/run/systemd/journal/flushed") < 0 && errno != ENOENT)
-+                log_warning_errno(errno, "Failed to unlink /run/systemd/journal/flushed, ignoring: %m");
-+
-+        return 0;
-+}
-+
- int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
-         Server *s = userdata;
-         struct ucred *ucred = NULL;
-@@ -1331,18 +1359,12 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void
- }
- 
- static void server_full_flush(Server *s) {
--        int r;
--
-         assert(s);
- 
-         (void) server_flush_to_var(s, false);
-         server_sync(s);
-         server_vacuum(s, false);
- 
--        r = touch("/run/systemd/journal/flushed");
--        if (r < 0)
--                log_warning_errno(r, "Failed to touch /run/systemd/journal/flushed, ignoring: %m");
--
-         server_space_usage_message(s, NULL);
- }
- 
-@@ -1351,7 +1373,7 @@ static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *
- 
-         assert(s);
- 
--        log_info("Received request to flush runtime journal from PID " PID_FMT, si->ssi_pid);
-+        log_info("Received SIGUSR1 signal from PID " PID_FMT ", as request to flush runtime journal.", si->ssi_pid);
-         server_full_flush(s);
- 
-         return 0;
-@@ -1381,7 +1403,7 @@ static int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo *
- 
-         assert(s);
- 
--        log_info("Received request to rotate journal from PID " PID_FMT, si->ssi_pid);
-+        log_info("Received SIGUSR2 signal from PID " PID_FMT ", as request to rotate journal.", si->ssi_pid);
-         server_full_rotate(s);
- 
-         return 0;
-@@ -1418,7 +1440,7 @@ static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo
- 
-         assert(s);
- 
--        log_debug("Received request to sync from PID " PID_FMT, si->ssi_pid);
-+        log_debug("Received SIGRTMIN1 signal from PID " PID_FMT ", as request to sync.", si->ssi_pid );
-         server_full_sync(s);
- 
-         return 0;
-@@ -1934,6 +1956,21 @@ static int vl_method_flush_to_var(Varlink *link, JsonVariant *parameters, Varlin
-         return varlink_reply(link, NULL);
- }
- 
-+static int vl_method_relinquish_var(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
-+        Server *s = userdata;
-+
-+        assert(link);
-+        assert(s);
-+
-+        if (json_variant_elements(parameters) > 0)
-+                return varlink_error_invalid_parameter(link, parameters);
-+
-+        log_info("Received client request to relinquish /var access.");
-+        server_relinquish_var(s);
-+
-+        return varlink_reply(link, NULL);
-+}
-+
- static int server_open_varlink(Server *s) {
-         int r;
- 
-@@ -1947,9 +1984,10 @@ static int server_open_varlink(Server *s) {
- 
-         r = varlink_server_bind_method_many(
-                         s->varlink_server,
--                        "io.systemd.Journal.Synchronize", vl_method_synchronize,
--                        "io.systemd.Journal.Rotate",      vl_method_rotate,
--                        "io.systemd.Journal.FlushToVar",  vl_method_flush_to_var);
-+                        "io.systemd.Journal.Synchronize",   vl_method_synchronize,
-+                        "io.systemd.Journal.Rotate",        vl_method_rotate,
-+                        "io.systemd.Journal.FlushToVar",    vl_method_flush_to_var,
-+                        "io.systemd.Journal.RelinquishVar", vl_method_relinquish_var);
-         if (r < 0)
-                 return r;
- 
-@@ -2164,7 +2202,7 @@ int server_init(Server *s) {
- 
-         (void) client_context_acquire_default(s);
- 
--        return system_journal_open(s, false);
-+        return system_journal_open(s, false, false);
- }
- 
- void server_maybe_append_tags(Server *s) {
diff --git a/debian/patches/apertis/journald-also-offer-flush-rotate-sync-as-varlink-method-c.patch b/debian/patches/apertis/journald-also-offer-flush-rotate-sync-as-varlink-method-c.patch
deleted file mode 100644
index faf3db351102d85af1deb7ecd97fb137a7badbb4..0000000000000000000000000000000000000000
--- a/debian/patches/apertis/journald-also-offer-flush-rotate-sync-as-varlink-method-c.patch
+++ /dev/null
@@ -1,236 +0,0 @@
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 4 Apr 2019 19:38:18 +0200
-Subject: journald: also offer flush/rotate/sync as varlink method calls
-
-This makes the operations previously available via asynchronous signals
-also available as regular varlink method calls, i.e. with sane
-completion.
-
-Signed-off-by: Martyn Welch <martyn.welch@collabora.com>
-[Martyn Welch: Backported to systemd v241]
----
- src/journal/journald-server.c | 125 ++++++++++++++++++++++++++++++++++++++----
- src/journal/journald-server.h |   3 +
- 2 files changed, 117 insertions(+), 11 deletions(-)
-
-diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
-index 7fe0f82..dc4b259 100644
---- a/src/journal/journald-server.c
-+++ b/src/journal/journald-server.c
-@@ -1330,14 +1330,11 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void
-         return 0;
- }
- 
--static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
--        Server *s = userdata;
-+static void server_full_flush(Server *s) {
-         int r;
- 
-         assert(s);
- 
--        log_info("Received request to flush runtime journal from PID " PID_FMT, si->ssi_pid);
--
-         (void) server_flush_to_var(s, false);
-         server_sync(s);
-         server_vacuum(s, false);
-@@ -1347,16 +1344,24 @@ static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *
-                 log_warning_errno(r, "Failed to touch /run/systemd/journal/flushed, ignoring: %m");
- 
-         server_space_usage_message(s, NULL);
--        return 0;
- }
- 
--static int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
-+static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
-         Server *s = userdata;
-+
-+        assert(s);
-+
-+        log_info("Received request to flush runtime journal from PID " PID_FMT, si->ssi_pid);
-+        server_full_flush(s);
-+
-+        return 0;
-+}
-+
-+static void server_full_rotate(Server *s) {
-         int r;
- 
-         assert(s);
- 
--        log_info("Received request to rotate journal from PID " PID_FMT, si->ssi_pid);
-         server_rotate(s);
-         server_vacuum(s, true);
- 
-@@ -1369,6 +1374,15 @@ static int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo *
-         r = write_timestamp_file_atomic("/run/systemd/journal/rotated", now(CLOCK_MONOTONIC));
-         if (r < 0)
-                 log_warning_errno(r, "Failed to write /run/systemd/journal/rotated, ignoring: %m");
-+}
-+
-+static int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
-+        Server *s = userdata;
-+
-+        assert(s);
-+
-+        log_info("Received request to rotate journal from PID " PID_FMT, si->ssi_pid);
-+        server_full_rotate(s);
- 
-         return 0;
- }
-@@ -1384,14 +1398,11 @@ static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *
-         return 0;
- }
- 
--static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
--        Server *s = userdata;
-+static void server_full_sync(Server *s) {
-         int r;
- 
-         assert(s);
- 
--        log_debug("Received request to sync from PID " PID_FMT, si->ssi_pid);
--
-         server_sync(s);
- 
-         /* Let clients know when the most recent sync happened. */
-@@ -1399,6 +1410,17 @@ static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo
-         if (r < 0)
-                 log_warning_errno(r, "Failed to write /run/systemd/journal/synced, ignoring: %m");
- 
-+        return;
-+}
-+
-+static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
-+        Server *s = userdata;
-+
-+        assert(s);
-+
-+        log_debug("Received request to sync from PID " PID_FMT, si->ssi_pid);
-+        server_full_sync(s);
-+
-         return 0;
- }
- 
-@@ -1813,6 +1835,81 @@ static int server_connect_notify(Server *s) {
-         return 0;
- }
- 
-+static int vl_method_synchronize(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
-+        Server *s = userdata;
-+
-+        assert(link);
-+        assert(s);
-+
-+        if (json_variant_elements(parameters) > 0)
-+                return varlink_error_invalid_parameter(link, parameters);
-+
-+        log_info("Received client request to rotate journal.");
-+        server_full_sync(s);
-+
-+        return varlink_reply(link, NULL);
-+}
-+
-+static int vl_method_rotate(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
-+        Server *s = userdata;
-+
-+        assert(link);
-+        assert(s);
-+
-+        if (json_variant_elements(parameters) > 0)
-+                return varlink_error_invalid_parameter(link, parameters);
-+
-+        log_info("Received client request to rotate journal.");
-+        server_full_rotate(s);
-+
-+        return varlink_reply(link, NULL);
-+}
-+
-+static int vl_method_flush_to_var(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
-+        Server *s = userdata;
-+
-+        assert(link);
-+        assert(s);
-+
-+        if (json_variant_elements(parameters) > 0)
-+                return varlink_error_invalid_parameter(link, parameters);
-+
-+        log_info("Received client request to flush runtime journal.");
-+        server_full_flush(s);
-+
-+        return varlink_reply(link, NULL);
-+}
-+
-+static int server_open_varlink(Server *s) {
-+        int r;
-+
-+        assert(s);
-+
-+        r = varlink_server_new(&s->varlink_server, VARLINK_SERVER_ROOT_ONLY);
-+        if (r < 0)
-+                return r;
-+
-+        varlink_server_set_userdata(s->varlink_server, s);
-+
-+        r = varlink_server_bind_method_many(
-+                        s->varlink_server,
-+                        "io.systemd.Journal.Synchronize", vl_method_synchronize,
-+                        "io.systemd.Journal.Rotate",      vl_method_rotate,
-+                        "io.systemd.Journal.FlushToVar",  vl_method_flush_to_var);
-+        if (r < 0)
-+                return r;
-+
-+        r = varlink_server_listen_address(s->varlink_server, "/run/systemd/journal/io.systemd.journal", 0600);
-+        if (r < 0)
-+                return r;
-+
-+        r = varlink_server_attach_event(s->varlink_server, s->event, SD_EVENT_PRIORITY_NORMAL);
-+        if (r < 0)
-+                return r;
-+
-+        return 0;
-+}
-+
- int server_init(Server *s) {
-         _cleanup_fdset_free_ FDSet *fds = NULL;
-         int n, r, fd;
-@@ -1973,6 +2070,10 @@ int server_init(Server *s) {
-                         return r;
-         }
- 
-+        r = server_open_varlink(s);
-+        if (r < 0)
-+                return r;
-+
-         r = server_open_kernel_seqnum(s);
-         if (r < 0)
-                 return r;
-@@ -2046,6 +2147,8 @@ void server_done(Server *s) {
- 
-         ordered_hashmap_free_with_destructor(s->user_journals, journal_file_close);
- 
-+        varlink_server_unref(s->varlink_server);
-+
-         sd_event_source_unref(s->syslog_event_source);
-         sd_event_source_unref(s->native_event_source);
-         sd_event_source_unref(s->stdout_event_source);
-diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
-index 3f6b42d..b44e658 100644
---- a/src/journal/journald-server.h
-+++ b/src/journal/journald-server.h
-@@ -16,6 +16,7 @@ typedef struct Server Server;
- #include "journald-stream.h"
- #include "list.h"
- #include "prioq.h"
-+#include "varlink.h"
- 
- typedef enum Storage {
-         STORAGE_AUTO,
-@@ -165,6 +166,8 @@ struct Server {
- 
-         ClientContext *my_context; /* the context of journald itself */
-         ClientContext *pid1_context; /* the context of PID 1 */
-+
-+        VarlinkServer *varlink_server;
- };
- 
- #define SERVER_MACHINE_ID(s) ((s)->machine_id_field + STRLEN("_MACHINE_ID="))
diff --git a/debian/patches/apertis/shared-add-minimal-varlink-implementation.patch b/debian/patches/apertis/shared-add-minimal-varlink-implementation.patch
deleted file mode 100644
index 437278cc263c8a53ac86c7715fc99300d64d3d13..0000000000000000000000000000000000000000
--- a/debian/patches/apertis/shared-add-minimal-varlink-implementation.patch
+++ /dev/null
@@ -1,2650 +0,0 @@
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 11 Apr 2019 18:46:54 +0200
-Subject: shared: add minimal varlink implementation
-
-This adds a minimal Varlink (https://varlink.org/) implementation to our
-tree. Given that we already have a JSON logic it's an easy thing to add.
-
-Why bother?
-
-We currently have major problems with IPC before dbus-daemon is up, and
-in all components that dbus-daemon itself makes use of (such as various
-NSS modules to resolve users as well as the journal which dbus-daemon
-logs to). Because of that we so far ended up creating various (usually
-crappy) work-arounds either coming up with secondary IPC systems or
-sharing data statelessly in /run or similar. Let's clean this up, and
-instead use a clean, well-defined, broker-less IPC for cases like that.
-
-This is a minimal implementation of Varlink, i.e. the most basic logic
-only. Stuff that's missing is left out on purpose: there's no
-introspection/validation and there's no name service. It might make
-sense to add that later, but for now let's only do the minimum buy-in we
-can get away with. In particular as I'd assume that at least initially
-we only use this IPC for our internal communication avoiding
-introspection and the name service should be fine.
-
-Specifically, I'd expect that we add IPC interfaces to the following
-concepts with this scheme:
-
-1. nss-resolve (so that hostname lookups with resolved work before
-   resolved is up)
-2. journald (so that IPC calls to journald don't have to go through
-   dbus-daemon thus creating a cyclic dependency between journald and
-   dbus-daemon)
-3. nss-systemd (so that dynamic user lookups via PID 1 work sanely even
-   inside of dbus-daemon, because otherwise we'd want to use dbus to run
-   dbus which causes deadlocks)
-4. networkd (to make sure one can talk to it in the initrd already,
-   long before dbus is around)
-
-And there might be other cases similar to this.
-
-Signed-off-by: Martyn Welch <martyn.welch@collabora.com>
-[Martyn Welch: Backported to systemd v241]
----
- src/shared/meson.build |    2 +
- src/shared/varlink.c   | 2412 ++++++++++++++++++++++++++++++++++++++++++++++++
- src/shared/varlink.h   |  162 ++++
- 3 files changed, 2576 insertions(+)
- create mode 100644 src/shared/varlink.c
- create mode 100644 src/shared/varlink.h
-
-diff --git a/src/shared/meson.build b/src/shared/meson.build
-index f6d1092..3a43168 100644
---- a/src/shared/meson.build
-+++ b/src/shared/meson.build
-@@ -153,6 +153,8 @@ shared_sources = files('''
-         uid-range.c
-         uid-range.h
-         utmp-wtmp.h
-+        varlink.c
-+        varlink.h
-         verbs.c
-         verbs.h
-         vlan-util.c
-diff --git a/src/shared/varlink.c b/src/shared/varlink.c
-new file mode 100644
-index 0000000..2a89f88
---- /dev/null
-+++ b/src/shared/varlink.c
-@@ -0,0 +1,2412 @@
-+/* SPDX-License-Identifier: LGPL-2.1+ */
-+
-+#include <sys/poll.h>
-+
-+#include "alloc-util.h"
-+#include "fd-util.h"
-+#include "hashmap.h"
-+#include "list.h"
-+#include "process-util.h"
-+#include "set.h"
-+#include "socket-util.h"
-+#include "string-table.h"
-+#include "string-util.h"
-+#include "strv.h"
-+#include "time-util.h"
-+#include "umask-util.h"
-+#include "user-util.h"
-+#include "util.h"
-+#include "varlink.h"
-+
-+/* Transient errors we might get on accept() that we should ignore. As per error handling comment in
-+ * the accept(2) man page. */
-+static inline bool ERRNO_IS_ACCEPT_AGAIN(int r) {
-+        return ERRNO_IS_DISCONNECT(r) ||
-+                IN_SET(abs(r),
-+                       EAGAIN,
-+                       EINTR,
-+                       EOPNOTSUPP);
-+}
-+
-+#define VARLINK_DEFAULT_CONNECTIONS_MAX 4096U
-+#define VARLINK_DEFAULT_CONNECTIONS_PER_UID_MAX 1024U
-+
-+#define VARLINK_DEFAULT_TIMEOUT_USEC (45U*USEC_PER_SEC)
-+#define VARLINK_BUFFER_MAX (16U*1024U*1024U)
-+#define VARLINK_READ_SIZE (64U*1024U)
-+
-+typedef enum VarlinkState {
-+        /* Client side states */
-+        VARLINK_IDLE_CLIENT,
-+        VARLINK_AWAITING_REPLY,
-+        VARLINK_CALLING,
-+        VARLINK_CALLED,
-+        VARLINK_PROCESSING_REPLY,
-+
-+        /* Server side states */
-+        VARLINK_IDLE_SERVER,
-+        VARLINK_PROCESSING_METHOD,
-+        VARLINK_PROCESSING_METHOD_MORE,
-+        VARLINK_PROCESSING_METHOD_ONEWAY,
-+        VARLINK_PROCESSED_METHOD,
-+        VARLINK_PROCESSED_METHOD_MORE,
-+        VARLINK_PENDING_METHOD,
-+        VARLINK_PENDING_METHOD_MORE,
-+
-+        /* Common states (only during shutdown) */
-+        VARLINK_PENDING_DISCONNECT,
-+        VARLINK_PENDING_TIMEOUT,
-+        VARLINK_PROCESSING_DISCONNECT,
-+        VARLINK_PROCESSING_TIMEOUT,
-+        VARLINK_PROCESSING_FAILURE,
-+        VARLINK_DISCONNECTED,
-+
-+        _VARLINK_STATE_MAX,
-+        _VARLINK_STATE_INVALID = -1
-+} VarlinkState;
-+
-+/* Tests whether we are not yet disconnected. Note that this is true during all states where the connection
-+ * is still good for something, and false only when it's dead for good. This means: when we are
-+ * asynchronously connecting to a peer and the connect() is still pending, then this will return 'true', as
-+ * the connection is still good, and we are likely to be able to properly operate on it soon. */
-+#define VARLINK_STATE_IS_ALIVE(state)                   \
-+        IN_SET(state,                                   \
-+               VARLINK_IDLE_CLIENT,                     \
-+               VARLINK_AWAITING_REPLY,                  \
-+               VARLINK_CALLING,                         \
-+               VARLINK_CALLED,                          \
-+               VARLINK_PROCESSING_REPLY,                \
-+               VARLINK_IDLE_SERVER,                     \
-+               VARLINK_PROCESSING_METHOD,               \
-+               VARLINK_PROCESSING_METHOD_MORE,          \
-+               VARLINK_PROCESSING_METHOD_ONEWAY,        \
-+               VARLINK_PROCESSED_METHOD,                \
-+               VARLINK_PROCESSED_METHOD_MORE,           \
-+               VARLINK_PENDING_METHOD,                  \
-+               VARLINK_PENDING_METHOD_MORE)
-+
-+struct Varlink {
-+        unsigned n_ref;
-+
-+        VarlinkServer *server;
-+
-+        VarlinkState state;
-+        bool connecting; /* This boolean indicates whether the socket fd we are operating on is currently
-+                          * processing an asynchronous connect(). In that state we watch the socket for
-+                          * EPOLLOUT, but we refrain from calling read() or write() on the socket as that
-+                          * will trigger ENOTCONN. Note that this boolean is kept separate from the
-+                          * VarlinkState above on purpose: while the connect() is still not complete we
-+                          * already want to allow queuing of messages and similar. Thus it's nice to keep
-+                          * these two state concepts separate: the VarlinkState encodes what our own view of
-+                          * the connection is, i.e. whether we think it's a server, a client, and has
-+                          * something queued already, while 'connecting' tells us a detail about the
-+                          * transport used below, that should have no effect on how we otherwise accept and
-+                          * process operations from the user.
-+                          *
-+                          * Or to say this differently: VARLINK_STATE_IS_ALIVE(state) tells you whether the
-+                          * connection is good to use, even if it might not be fully connected
-+                          * yet. connecting=true then informs you that actually we are still connecting, and
-+                          * the connection is actually not established yet and thus any requests you enqueue
-+                          * now will still work fine but will be queued only, not sent yet, but that
-+                          * shouldn't stop you from using the connection, since eventually whatever you queue
-+                          * *will* be sent.
-+                          *
-+                          * Or to say this even differently: 'state' is a high-level ("application layer"
-+                          * high, if you so will) state, while 'conecting' is a low-level ("transport layer"
-+                          * low, if you so will) state, and while they are not entirely unrelated and
-+                          * sometimes propagate effects to each other they are only asynchronously connected
-+                          * at most. */
-+        unsigned n_pending;
-+
-+        int fd;
-+
-+        char *input_buffer; /* valid data starts at input_buffer_index, ends at input_buffer_index+input_buffer_size */
-+        size_t input_buffer_allocated;
-+        size_t input_buffer_index;
-+        size_t input_buffer_size;
-+        size_t input_buffer_unscanned;
-+
-+        char *output_buffer; /* valid data starts at output_buffer_index, ends at output_buffer_index+output_buffer_size */
-+        size_t output_buffer_allocated;
-+        size_t output_buffer_index;
-+        size_t output_buffer_size;
-+
-+        VarlinkReply reply_callback;
-+
-+        JsonVariant *current;
-+        JsonVariant *reply;
-+
-+        struct ucred ucred;
-+        bool ucred_acquired:1;
-+
-+        bool write_disconnected:1;
-+        bool read_disconnected:1;
-+        bool prefer_read_write:1;
-+        bool got_pollhup:1;
-+
-+        usec_t timestamp;
-+        usec_t timeout;
-+
-+        void *userdata;
-+        char *description;
-+
-+        sd_event *event;
-+        sd_event_source *io_event_source;
-+        sd_event_source *time_event_source;
-+        sd_event_source *quit_event_source;
-+        sd_event_source *defer_event_source;
-+};
-+
-+typedef struct VarlinkServerSocket VarlinkServerSocket;
-+
-+struct VarlinkServerSocket {
-+        VarlinkServer *server;
-+
-+        int fd;
-+        char *address;
-+
-+        sd_event_source *event_source;
-+
-+        LIST_FIELDS(VarlinkServerSocket, sockets);
-+};
-+
-+struct VarlinkServer {
-+        unsigned n_ref;
-+        VarlinkServerFlags flags;
-+
-+        LIST_HEAD(VarlinkServerSocket, sockets);
-+
-+        Hashmap *methods;
-+        VarlinkConnect connect_callback;
-+
-+        sd_event *event;
-+        int64_t event_priority;
-+
-+        unsigned n_connections;
-+        Hashmap *by_uid;
-+
-+        void *userdata;
-+        char *description;
-+
-+        unsigned connections_max;
-+        unsigned connections_per_uid_max;
-+};
-+
-+static const char* const varlink_state_table[_VARLINK_STATE_MAX] = {
-+        [VARLINK_IDLE_CLIENT]              = "idle-client",
-+        [VARLINK_AWAITING_REPLY]           = "awaiting-reply",
-+        [VARLINK_CALLING]                  = "calling",
-+        [VARLINK_CALLED]                   = "called",
-+        [VARLINK_PROCESSING_REPLY]         = "processing-reply",
-+        [VARLINK_IDLE_SERVER]              = "idle-server",
-+        [VARLINK_PROCESSING_METHOD]        = "processing-method",
-+        [VARLINK_PROCESSING_METHOD_MORE]   = "processing-method-more",
-+        [VARLINK_PROCESSING_METHOD_ONEWAY] = "processing-method-oneway",
-+        [VARLINK_PROCESSED_METHOD]         = "processed-method",
-+        [VARLINK_PROCESSED_METHOD_MORE]    = "processed-method-more",
-+        [VARLINK_PENDING_METHOD]           = "pending-method",
-+        [VARLINK_PENDING_METHOD_MORE]      = "pending-method-more",
-+        [VARLINK_PENDING_DISCONNECT]       = "pending-disconnect",
-+        [VARLINK_PENDING_TIMEOUT]          = "pending-timeout",
-+        [VARLINK_PROCESSING_DISCONNECT]    = "processing-disconnect",
-+        [VARLINK_PROCESSING_TIMEOUT]       = "processing-timeout",
-+        [VARLINK_PROCESSING_FAILURE]       = "processing-failure",
-+        [VARLINK_DISCONNECTED]             = "disconnected",
-+};
-+
-+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(varlink_state, VarlinkState);
-+
-+#define varlink_log_errno(v, error, fmt, ...)                           \
-+        log_debug_errno(error, "%s: " fmt, varlink_description(v), ##__VA_ARGS__)
-+
-+#define varlink_log(v, fmt, ...)                                        \
-+        log_debug("%s: " fmt, varlink_description(v), ##__VA_ARGS__)
-+
-+#define varlink_server_log_errno(s, error, fmt, ...) \
-+        log_debug_errno(error, "%s: " fmt, varlink_server_description(s), ##__VA_ARGS__)
-+
-+#define varlink_server_log(s, fmt, ...) \
-+        log_debug("%s: " fmt, varlink_server_description(s), ##__VA_ARGS__)
-+
-+static inline const char *varlink_description(Varlink *v) {
-+        return strna(v ? v->description : NULL);
-+}
-+
-+static inline const char *varlink_server_description(VarlinkServer *s) {
-+        return strna(s ? s->description : NULL);
-+}
-+
-+static void varlink_set_state(Varlink *v, VarlinkState state) {
-+        assert(v);
-+
-+        varlink_log(v, "varlink: changing state %s → %s",
-+                  varlink_state_to_string(v->state),
-+                  varlink_state_to_string(state));
-+
-+        v->state = state;
-+}
-+
-+static int varlink_new(Varlink **ret) {
-+        Varlink *v;
-+
-+        assert(ret);
-+
-+        v = new(Varlink, 1);
-+        if (!v)
-+                return -ENOMEM;
-+
-+        *v = (Varlink) {
-+                .n_ref = 1,
-+                .fd = -1,
-+
-+                .state = _VARLINK_STATE_INVALID,
-+
-+                .ucred.uid = UID_INVALID,
-+                .ucred.gid = GID_INVALID,
-+
-+                .timestamp = USEC_INFINITY,
-+                .timeout = VARLINK_DEFAULT_TIMEOUT_USEC
-+        };
-+
-+        *ret = v;
-+        return 0;
-+}
-+
-+int varlink_connect_address(Varlink **ret, const char *address) {
-+        _cleanup_(varlink_unrefp) Varlink *v = NULL;
-+        union sockaddr_union sockaddr;
-+        int r;
-+
-+        assert_return(ret, -EINVAL);
-+        assert_return(address, -EINVAL);
-+
-+        r = sockaddr_un_set_path(&sockaddr.un, address);
-+        if (r < 0)
-+                return r;
-+
-+        r = varlink_new(&v);
-+        if (r < 0)
-+                return r;
-+
-+        v->fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
-+        if (v->fd < 0)
-+                return -errno;
-+
-+        if (connect(v->fd, &sockaddr.sa, SOCKADDR_UN_LEN(sockaddr.un)) < 0) {
-+                if (!IN_SET(errno, EAGAIN, EINPROGRESS))
-+                        return -errno;
-+
-+                v->connecting = true; /* We are asynchronously connecting, i.e. the connect() is being
-+                                       * processed in the background. As long as that's the case the socket
-+                                       * is in a special state: it's there, we can poll it for EPOLLOUT, but
-+                                       * if we attempt to write() to it before we see EPOLLOUT we'll get
-+                                       * ENOTCONN (and not EAGAIN, like we would for a normal connected
-+                                       * socket that isn't writable at the moment). Since ENOTCONN on write()
-+                                       * hence can mean two different things (i.e. connection not complete
-+                                       * yet vs. already disconnected again), we store as a boolean whether
-+                                       * we are still in connect(). */
-+        }
-+
-+        varlink_set_state(v, VARLINK_IDLE_CLIENT);
-+
-+        *ret = TAKE_PTR(v);
-+        return r;
-+}
-+
-+int varlink_connect_fd(Varlink **ret, int fd) {
-+        Varlink *v;
-+        int r;
-+
-+        assert_return(ret, -EINVAL);
-+        assert_return(fd >= 0, -EBADF);
-+
-+        r = fd_nonblock(fd, true);
-+        if (r < 0)
-+                return r;
-+
-+        r = varlink_new(&v);
-+        if (r < 0)
-+                return r;
-+
-+        v->fd = fd;
-+        varlink_set_state(v, VARLINK_IDLE_CLIENT);
-+
-+        /* Note that if this function is called we assume the passed socket (if it is one) is already
-+         * properly connected, i.e. any asynchronous connect() done on it already completed. Because of that
-+         * we'll not set the 'connecting' boolean here, i.e. we don't need to avoid write()ing to the socket
-+         * until the connection is fully set up. Behaviour here is hence a bit different from
-+         * varlink_connect_address() above, as there we do handle asynchronous connections ourselves and
-+         * avoid doing write() on it before we saw EPOLLOUT for the first time. */
-+
-+        *ret = v;
-+        return 0;
-+}
-+
-+static void varlink_detach_event_sources(Varlink *v) {
-+        assert(v);
-+
-+        if (v->io_event_source) {
-+                (void) sd_event_source_set_enabled(v->io_event_source, SD_EVENT_OFF);
-+                v->io_event_source = sd_event_source_unref(v->io_event_source);
-+        }
-+
-+        if (v->time_event_source) {
-+                (void) sd_event_source_set_enabled(v->time_event_source, SD_EVENT_OFF);
-+                v->time_event_source = sd_event_source_unref(v->time_event_source);
-+        }
-+
-+        if (v->quit_event_source) {
-+                (void) sd_event_source_set_enabled(v->quit_event_source, SD_EVENT_OFF);
-+                v->quit_event_source = sd_event_source_unref(v->quit_event_source);
-+        }
-+
-+        if (v->defer_event_source) {
-+                (void) sd_event_source_set_enabled(v->defer_event_source, SD_EVENT_OFF);
-+                v->defer_event_source = sd_event_source_unref(v->defer_event_source);
-+        }
-+}
-+
-+static void varlink_clear(Varlink *v) {
-+        assert(v);
-+
-+        varlink_detach_event_sources(v);
-+
-+        v->fd = safe_close(v->fd);
-+
-+        v->input_buffer = mfree(v->input_buffer);
-+        v->output_buffer = mfree(v->output_buffer);
-+
-+        v->current = json_variant_unref(v->current);
-+        v->reply = json_variant_unref(v->reply);
-+
-+        v->event = sd_event_unref(v->event);
-+}
-+
-+static Varlink* varlink_destroy(Varlink *v) {
-+        if (!v)
-+                return NULL;
-+
-+        /* If this is called the server object must already been unreffed here. Why that? because when we
-+         * linked up the varlink connection with the server object we took one ref in each direction */
-+        assert(!v->server);
-+
-+        varlink_clear(v);
-+
-+        free(v->description);
-+        return mfree(v);
-+}
-+
-+DEFINE_TRIVIAL_REF_UNREF_FUNC(Varlink, varlink, varlink_destroy);
-+
-+static int varlink_test_disconnect(Varlink *v) {
-+        assert(v);
-+
-+        /* Tests whether we the the connection has been terminated. We are careful to not stop processing it
-+         * prematurely, since we want to handle half-open connections as well as possible and want to flush
-+         * out and read data before we close down if we can. */
-+
-+        /* Already disconnected? */
-+        if (!VARLINK_STATE_IS_ALIVE(v->state))
-+                return 0;
-+
-+        /* Wait until connection setup is complete, i.e. until asynchronous connect() completes */
-+        if (v->connecting)
-+                return 0;
-+
-+        /* Still something to write and we can write? Stay around */
-+        if (v->output_buffer_size > 0 && !v->write_disconnected)
-+                return 0;
-+
-+        /* Both sides gone already? Then there's no need to stick around */
-+        if (v->read_disconnected && v->write_disconnected)
-+                goto disconnect;
-+
-+        /* If we are waiting for incoming data but the read side is shut down, disconnect. */
-+        if (IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_CALLING, VARLINK_IDLE_SERVER) && v->read_disconnected)
-+                goto disconnect;
-+
-+        /* Similar, if are a client that hasn't written anything yet but the write side is dead, also
-+         * disconnect. We also explicitly check for POLLHUP here since we likely won't notice the write side
-+         * being down if we never wrote anything. */
-+        if (IN_SET(v->state, VARLINK_IDLE_CLIENT) && (v->write_disconnected || v->got_pollhup))
-+                goto disconnect;
-+
-+        return 0;
-+
-+disconnect:
-+        varlink_set_state(v, VARLINK_PENDING_DISCONNECT);
-+        return 1;
-+}
-+
-+static int varlink_write(Varlink *v) {
-+        ssize_t n;
-+
-+        assert(v);
-+
-+        if (!VARLINK_STATE_IS_ALIVE(v->state))
-+                return 0;
-+        if (v->connecting) /* Writing while we are still wait for a non-blocking connect() to complete will
-+                            * result in ENOTCONN, hence exit early here */
-+                return 0;
-+        if (v->output_buffer_size == 0)
-+                return 0;
-+        if (v->write_disconnected)
-+                return 0;
-+
-+        assert(v->fd >= 0);
-+
-+        /* We generally prefer recv()/send() (mostly because of MSG_NOSIGNAL) but also want to be compatible
-+         * with non-socket IO, hence fall back automatically */
-+        if (!v->prefer_read_write) {
-+                n = send(v->fd, v->output_buffer + v->output_buffer_index, v->output_buffer_size, MSG_DONTWAIT|MSG_NOSIGNAL);
-+                if (n < 0 && errno == ENOTSOCK)
-+                        v->prefer_read_write = true;
-+        }
-+        if (v->prefer_read_write)
-+                n = write(v->fd, v->output_buffer + v->output_buffer_index, v->output_buffer_size);
-+        if (n < 0) {
-+                if (errno == EAGAIN)
-+                        return 0;
-+
-+                if (ERRNO_IS_DISCONNECT(errno)) {
-+                        /* If we get informed about a disconnect on write, then let's remember that, but not
-+                         * act on it just yet. Let's wait for read() to report the issue first. */
-+                        v->write_disconnected = true;
-+                        return 1;
-+                }
-+
-+                return -errno;
-+        }
-+
-+        v->output_buffer_size -= n;
-+
-+        if (v->output_buffer_size == 0)
-+                v->output_buffer_index = 0;
-+        else
-+                v->output_buffer_index += n;
-+
-+        v->timestamp = now(CLOCK_MONOTONIC);
-+        return 1;
-+}
-+
-+static int varlink_read(Varlink *v) {
-+        size_t rs;
-+        ssize_t n;
-+
-+        assert(v);
-+
-+        if (!IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_CALLING, VARLINK_IDLE_SERVER))
-+                return 0;
-+        if (v->connecting) /* read() on a socket while we are in connect() will fail with EINVAL, hence exit early here */
-+                return 0;
-+        if (v->current)
-+                return 0;
-+        if (v->input_buffer_unscanned > 0)
-+                return 0;
-+        if (v->read_disconnected)
-+                return 0;
-+
-+        if (v->input_buffer_size >= VARLINK_BUFFER_MAX)
-+                return -ENOBUFS;
-+
-+        assert(v->fd >= 0);
-+
-+        if (v->input_buffer_allocated <= v->input_buffer_index + v->input_buffer_size) {
-+                size_t add;
-+
-+                add = MIN(VARLINK_BUFFER_MAX - v->input_buffer_size, VARLINK_READ_SIZE);
-+
-+                if (v->input_buffer_index == 0) {
-+
-+                        if (!GREEDY_REALLOC(v->input_buffer, v->input_buffer_allocated, v->input_buffer_size + add))
-+                                return -ENOMEM;
-+
-+                } else {
-+                        char *b;
-+
-+                        b = new(char, v->input_buffer_size + add);
-+                        if (!b)
-+                                return -ENOMEM;
-+
-+                        memcpy(b, v->input_buffer + v->input_buffer_index, v->input_buffer_size);
-+
-+                        free_and_replace(v->input_buffer, b);
-+
-+                        v->input_buffer_allocated = v->input_buffer_size + add;
-+                        v->input_buffer_index = 0;
-+                }
-+        }
-+
-+        rs = v->input_buffer_allocated - (v->input_buffer_index + v->input_buffer_size);
-+
-+        if (!v->prefer_read_write) {
-+                n = recv(v->fd, v->input_buffer + v->input_buffer_index + v->input_buffer_size, rs, MSG_DONTWAIT);
-+                if (n < 0 && errno == ENOTSOCK)
-+                        v->prefer_read_write = true;
-+        }
-+        if (v->prefer_read_write)
-+                n = read(v->fd, v->input_buffer + v->input_buffer_index + v->input_buffer_size, rs);
-+        if (n < 0) {
-+                if (errno == EAGAIN)
-+                        return 0;
-+
-+                if (ERRNO_IS_DISCONNECT(errno)) {
-+                        v->read_disconnected = true;
-+                        return 1;
-+                }
-+
-+                return -errno;
-+        }
-+        if (n == 0) { /* EOF */
-+                v->read_disconnected = true;
-+                return 1;
-+        }
-+
-+        v->input_buffer_size += n;
-+        v->input_buffer_unscanned += n;
-+
-+        return 1;
-+}
-+
-+static int varlink_parse_message(Varlink *v) {
-+        const char *e, *begin;
-+        size_t sz;
-+        int r;
-+
-+        assert(v);
-+
-+        if (v->current)
-+                return 0;
-+        if (v->input_buffer_unscanned <= 0)
-+                return 0;
-+
-+        assert(v->input_buffer_unscanned <= v->input_buffer_size);
-+        assert(v->input_buffer_index + v->input_buffer_size <= v->input_buffer_allocated);
-+
-+        begin = v->input_buffer + v->input_buffer_index;
-+
-+        e = memchr(begin + v->input_buffer_size - v->input_buffer_unscanned, 0, v->input_buffer_unscanned);
-+        if (!e) {
-+                v->input_buffer_unscanned = 0;
-+                return 0;
-+        }
-+
-+        sz = e - begin + 1;
-+
-+        varlink_log(v, "New incoming message: %s", begin);
-+
-+        r = json_parse(begin, &v->current, NULL, NULL);
-+        if (r < 0)
-+                return r;
-+
-+        v->input_buffer_size -= sz;
-+
-+        if (v->input_buffer_size == 0)
-+                v->input_buffer_index = 0;
-+        else
-+                v->input_buffer_index += sz;
-+
-+        v->input_buffer_unscanned = v->input_buffer_size;
-+        return 1;
-+}
-+
-+static int varlink_test_timeout(Varlink *v) {
-+        assert(v);
-+
-+        if (!IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_CALLING))
-+                return 0;
-+        if (v->timeout == USEC_INFINITY)
-+                return 0;
-+
-+        if (now(CLOCK_MONOTONIC) < usec_add(v->timestamp, v->timeout))
-+                return 0;
-+
-+        varlink_set_state(v, VARLINK_PENDING_TIMEOUT);
-+
-+        return 1;
-+}
-+
-+static int varlink_dispatch_local_error(Varlink *v, const char *error) {
-+        int r;
-+
-+        assert(v);
-+        assert(error);
-+
-+        if (!v->reply_callback)
-+                return 0;
-+
-+        r = v->reply_callback(v, NULL, error, VARLINK_REPLY_ERROR|VARLINK_REPLY_LOCAL, v->userdata);
-+        if (r < 0)
-+                log_debug_errno(r, "Reply callback returned error, ignoring: %m");
-+
-+        return 1;
-+}
-+
-+static int varlink_dispatch_timeout(Varlink *v) {
-+        assert(v);
-+
-+        if (v->state != VARLINK_PENDING_TIMEOUT)
-+                return 0;
-+
-+        varlink_set_state(v, VARLINK_PROCESSING_TIMEOUT);
-+        varlink_dispatch_local_error(v, VARLINK_ERROR_TIMEOUT);
-+        varlink_close(v);
-+
-+        return 1;
-+}
-+
-+static int varlink_dispatch_disconnect(Varlink *v) {
-+        assert(v);
-+
-+        if (v->state != VARLINK_PENDING_DISCONNECT)
-+                return 0;
-+
-+        varlink_set_state(v, VARLINK_PROCESSING_DISCONNECT);
-+        varlink_dispatch_local_error(v, VARLINK_ERROR_DISCONNECTED);
-+        varlink_close(v);
-+
-+        return 1;
-+}
-+
-+static int varlink_sanitize_parameters(JsonVariant **v) {
-+        assert(v);
-+
-+        /* Varlink always wants a parameters list, hence make one if the caller doesn't want any */
-+        if (!*v)
-+                return json_variant_new_object(v, NULL, 0);
-+        else if (!json_variant_is_object(*v))
-+                return -EINVAL;
-+
-+        return 0;
-+}
-+
-+static int varlink_dispatch_reply(Varlink *v) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *parameters = NULL;
-+        VarlinkReplyFlags flags = 0;
-+        const char *error = NULL;
-+        JsonVariant *k, *e;
-+        int r;
-+
-+        assert(v);
-+
-+        if (!IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_CALLING))
-+                return 0;
-+        if (!v->current)
-+                return 0;
-+
-+        assert(v->n_pending > 0);
-+
-+        if (!json_variant_is_object(v->current))
-+                goto invalid;
-+
-+        JSON_VARIANT_OBJECT_FOREACH(k, e, v->current) {
-+                const char *n;
-+
-+                assert_se(n = json_variant_string(k));
-+
-+                if (streq(n, "error")) {
-+                        if (error)
-+                                goto invalid;
-+                        if (!json_variant_is_string(e))
-+                                goto invalid;
-+
-+                        error = json_variant_string(e);
-+                        flags |= VARLINK_REPLY_ERROR;
-+
-+                } else if (streq(n, "parameters")) {
-+                        if (parameters)
-+                                goto invalid;
-+                        if (!json_variant_is_object(e))
-+                                goto invalid;
-+
-+                        parameters = json_variant_ref(e);
-+
-+                } else if (streq(n, "continues")) {
-+                        if (FLAGS_SET(flags, VARLINK_REPLY_CONTINUES))
-+                                goto invalid;
-+
-+                        if (!json_variant_is_boolean(e))
-+                                goto invalid;
-+
-+                        if (json_variant_boolean(e))
-+                                flags |= VARLINK_REPLY_CONTINUES;
-+                } else
-+                        goto invalid;
-+        }
-+
-+        if (error && FLAGS_SET(flags, VARLINK_REPLY_CONTINUES))
-+                goto invalid;
-+
-+        r = varlink_sanitize_parameters(&parameters);
-+        if (r < 0)
-+                goto invalid;
-+
-+        if (v->state == VARLINK_AWAITING_REPLY) {
-+                varlink_set_state(v, VARLINK_PROCESSING_REPLY);
-+
-+                if (v->reply_callback) {
-+                        r = v->reply_callback(v, parameters, error, flags, v->userdata);
-+                        if (r < 0)
-+                                log_debug_errno(r, "Reply callback returned error, ignoring: %m");
-+                }
-+
-+                v->current = json_variant_unref(v->current);
-+
-+                if (v->state == VARLINK_PROCESSING_REPLY) {
-+                        assert(v->n_pending > 0);
-+                        v->n_pending--;
-+
-+                        varlink_set_state(v, v->n_pending == 0 ? VARLINK_IDLE_CLIENT : VARLINK_AWAITING_REPLY);
-+                }
-+        } else {
-+                assert(v->state == VARLINK_CALLING);
-+
-+                if (FLAGS_SET(flags, VARLINK_REPLY_CONTINUES))
-+                        goto invalid;
-+
-+                varlink_set_state(v, VARLINK_CALLED);
-+        }
-+
-+        return 1;
-+
-+invalid:
-+        varlink_set_state(v, VARLINK_PROCESSING_FAILURE);
-+        varlink_dispatch_local_error(v, VARLINK_ERROR_PROTOCOL);
-+        varlink_close(v);
-+
-+        return 1;
-+}
-+
-+static int varlink_dispatch_method(Varlink *v) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *parameters = NULL;
-+        VarlinkMethodFlags flags = 0;
-+        const char *method = NULL, *error;
-+        JsonVariant *k, *e;
-+        VarlinkMethod callback;
-+        int r;
-+
-+        assert(v);
-+
-+        if (v->state != VARLINK_IDLE_SERVER)
-+                return 0;
-+        if (!v->current)
-+                return 0;
-+
-+        if (!json_variant_is_object(v->current))
-+                goto invalid;
-+
-+        JSON_VARIANT_OBJECT_FOREACH(k, e, v->current) {
-+                const char *n;
-+
-+                assert_se(n = json_variant_string(k));
-+
-+                if (streq(n, "method")) {
-+                        if (method)
-+                                goto invalid;
-+                        if (!json_variant_is_string(e))
-+                                goto invalid;
-+
-+                        method = json_variant_string(e);
-+
-+                } else if (streq(n, "parameters")) {
-+                        if (parameters)
-+                                goto invalid;
-+                        if (!json_variant_is_object(e))
-+                                goto invalid;
-+
-+                        parameters = json_variant_ref(e);
-+
-+                } else if (streq(n, "oneway")) {
-+
-+                        if ((flags & (VARLINK_METHOD_ONEWAY|VARLINK_METHOD_MORE)) != 0)
-+                                goto invalid;
-+
-+                        if (!json_variant_is_boolean(e))
-+                                goto invalid;
-+
-+                        if (json_variant_boolean(e))
-+                                flags |= VARLINK_METHOD_ONEWAY;
-+
-+                } else if (streq(n, "more")) {
-+
-+                        if ((flags & (VARLINK_METHOD_ONEWAY|VARLINK_METHOD_MORE)) != 0)
-+                                goto invalid;
-+
-+                        if (!json_variant_is_boolean(e))
-+                                goto invalid;
-+
-+                        if (json_variant_boolean(e))
-+                                flags |= VARLINK_METHOD_MORE;
-+
-+                } else
-+                        goto invalid;
-+        }
-+
-+        if (!method)
-+                goto invalid;
-+
-+        r = varlink_sanitize_parameters(&parameters);
-+        if (r < 0)
-+                goto fail;
-+
-+        varlink_set_state(v, (flags & VARLINK_METHOD_MORE)   ? VARLINK_PROCESSING_METHOD_MORE :
-+                             (flags & VARLINK_METHOD_ONEWAY) ? VARLINK_PROCESSING_METHOD_ONEWAY :
-+                                                               VARLINK_PROCESSING_METHOD);
-+
-+        assert(v->server);
-+
-+        if (STR_IN_SET(method, "org.varlink.service.GetInfo", "org.varlink.service.GetInterface")) {
-+                /* For now, we don't implement a single of varlink's own methods */
-+                callback = NULL;
-+                error = VARLINK_ERROR_METHOD_NOT_IMPLEMENTED;
-+        } else if (startswith(method, "org.varlink.service.")) {
-+                callback = NULL;
-+                error = VARLINK_ERROR_METHOD_NOT_FOUND;
-+        } else {
-+                callback = hashmap_get(v->server->methods, method);
-+                error = VARLINK_ERROR_METHOD_NOT_FOUND;
-+        }
-+
-+        if (callback) {
-+                r = callback(v, parameters, flags, v->userdata);
-+                if (r < 0) {
-+                        log_debug_errno(r, "Callback for %s returned error: %m", method);
-+
-+                        /* We got an error back from the callback. Propagate it to the client if the method call remains unanswered. */
-+                        if (!FLAGS_SET(flags, VARLINK_METHOD_ONEWAY)) {
-+                                r = varlink_errorb(v, VARLINK_ERROR_SYSTEM, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("errno", JSON_BUILD_INTEGER(-r))));
-+                                if (r < 0)
-+                                        return r;
-+                        }
-+                }
-+        } else if (!FLAGS_SET(flags, VARLINK_METHOD_ONEWAY)) {
-+                assert(error);
-+
-+                r = varlink_errorb(v, error, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("method", JSON_BUILD_STRING(method))));
-+                if (r < 0)
-+                        return r;
-+        }
-+
-+        switch (v->state) {
-+
-+        case VARLINK_PROCESSED_METHOD: /* Method call is fully processed */
-+        case VARLINK_PROCESSING_METHOD_ONEWAY: /* ditto */
-+                v->current = json_variant_unref(v->current);
-+                varlink_set_state(v, VARLINK_IDLE_SERVER);
-+                break;
-+
-+        case VARLINK_PROCESSING_METHOD: /* Method call wasn't replied to, will be replied to later */
-+                varlink_set_state(v, VARLINK_PENDING_METHOD);
-+                break;
-+
-+        case VARLINK_PROCESSED_METHOD_MORE:  /* One reply for a "more" message was sent, more to come */
-+        case VARLINK_PROCESSING_METHOD_MORE: /* No reply for a "more" message was sent, more to come */
-+                varlink_set_state(v, VARLINK_PENDING_METHOD_MORE);
-+                break;
-+
-+        default:
-+                assert_not_reached("Unexpected state");
-+
-+        }
-+
-+        return r;
-+
-+invalid:
-+        r = -EINVAL;
-+
-+fail:
-+        varlink_set_state(v, VARLINK_PROCESSING_FAILURE);
-+        varlink_dispatch_local_error(v, VARLINK_ERROR_PROTOCOL);
-+        varlink_close(v);
-+
-+        return r;
-+}
-+
-+int varlink_process(Varlink *v) {
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return -ENOTCONN;
-+
-+        varlink_ref(v);
-+
-+        r = varlink_write(v);
-+        if (r != 0)
-+                goto finish;
-+
-+        r = varlink_dispatch_reply(v);
-+        if (r != 0)
-+                goto finish;
-+
-+        r = varlink_dispatch_method(v);
-+        if (r != 0)
-+                goto finish;
-+
-+        r = varlink_parse_message(v);
-+        if (r != 0)
-+                goto finish;
-+
-+        r = varlink_read(v);
-+        if (r != 0)
-+                goto finish;
-+
-+        r = varlink_test_disconnect(v);
-+        if (r != 0)
-+                goto finish;
-+
-+        r = varlink_dispatch_disconnect(v);
-+        if (r != 0)
-+                goto finish;
-+
-+        r = varlink_test_timeout(v);
-+        if (r != 0)
-+                goto finish;
-+
-+        r = varlink_dispatch_timeout(v);
-+        if (r != 0)
-+                goto finish;
-+
-+finish:
-+        if (r >= 0 && v->defer_event_source) {
-+                int q;
-+
-+                /* If we did some processing, make sure we are called again soon */
-+                q = sd_event_source_set_enabled(v->defer_event_source, r > 0 ? SD_EVENT_ON : SD_EVENT_OFF);
-+                if (q < 0)
-+                        r = q;
-+        }
-+
-+        if (r < 0) {
-+                if (VARLINK_STATE_IS_ALIVE(v->state))
-+                        /* Initiate disconnection */
-+                        varlink_set_state(v, VARLINK_PENDING_DISCONNECT);
-+                else
-+                        /* We failed while disconnecting, in that case close right away */
-+                        varlink_close(v);
-+        }
-+
-+        varlink_unref(v);
-+        return r;
-+}
-+
-+static void handle_revents(Varlink *v, int revents) {
-+        assert(v);
-+
-+        if (v->connecting) {
-+                /* If we have seen POLLOUT or POLLHUP on a socket we are asynchronously waiting a connect()
-+                 * to complete on, we know we are ready. We don't read the connection error here though,
-+                 * we'll get the error on the next read() or write(). */
-+                if ((revents & (POLLOUT|POLLHUP)) == 0)
-+                        return;
-+
-+                varlink_log(v, "Anynchronous connection completed.");
-+                v->connecting = false;
-+        } else {
-+                /* Note that we don't care much about POLLIN/POLLOUT here, we'll just try reading and writing
-+                 * what we can. However, we do care about POLLHUP to detect connection termination even if we
-+                 * momentarily don't want to read nor write anything. */
-+
-+                if (!FLAGS_SET(revents, POLLHUP))
-+                        return;
-+
-+                varlink_log(v, "Got POLLHUP from socket.");
-+                v->got_pollhup = true;
-+        }
-+}
-+
-+int varlink_wait(Varlink *v, usec_t timeout) {
-+        struct timespec ts;
-+        struct pollfd pfd;
-+        int r, fd, events;
-+        usec_t t;
-+
-+        assert_return(v, -EINVAL);
-+        assert_return(!v->server, -ENOTTY);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return -ENOTCONN;
-+
-+        r = varlink_get_timeout(v, &t);
-+        if (r < 0)
-+                return r;
-+        if (t != USEC_INFINITY) {
-+                usec_t n;
-+
-+                n = now(CLOCK_MONOTONIC);
-+                if (t < n)
-+                        t = 0;
-+                else
-+                        t = usec_sub_unsigned(t, n);
-+        }
-+
-+        if (timeout != USEC_INFINITY &&
-+            (t == USEC_INFINITY || timeout < t))
-+                t = timeout;
-+
-+        fd = varlink_get_fd(v);
-+        if (fd < 0)
-+                return fd;
-+
-+        events = varlink_get_events(v);
-+        if (events < 0)
-+                return events;
-+
-+        pfd = (struct pollfd) {
-+                .fd = fd,
-+                .events = events,
-+        };
-+
-+        r = ppoll(&pfd, 1,
-+                  t == USEC_INFINITY ? NULL : timespec_store(&ts, t),
-+                  NULL);
-+        if (r < 0)
-+                return -errno;
-+
-+        handle_revents(v, pfd.revents);
-+
-+        return r > 0 ? 1 : 0;
-+}
-+
-+int varlink_get_fd(Varlink *v) {
-+
-+        assert_return(v, -EINVAL);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return -ENOTCONN;
-+        if (v->fd < 0)
-+                return -EBADF;
-+
-+        return v->fd;
-+}
-+
-+int varlink_get_events(Varlink *v) {
-+        int ret = 0;
-+
-+        assert_return(v, -EINVAL);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return -ENOTCONN;
-+
-+        if (v->connecting) /* When processing an asynchronous connect(), we only wait for EPOLLOUT, which
-+                            * tells us that the connection is now complete. Before that we should neither
-+                            * write() or read() from the fd. */
-+                return EPOLLOUT;
-+
-+        if (!v->read_disconnected &&
-+            IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_CALLING, VARLINK_IDLE_SERVER) &&
-+            !v->current &&
-+            v->input_buffer_unscanned <= 0)
-+                ret |= EPOLLIN;
-+
-+        if (!v->write_disconnected &&
-+            v->output_buffer_size > 0)
-+                ret |= EPOLLOUT;
-+
-+        return ret;
-+}
-+
-+int varlink_get_timeout(Varlink *v, usec_t *ret) {
-+        assert_return(v, -EINVAL);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return -ENOTCONN;
-+
-+        if (IN_SET(v->state, VARLINK_AWAITING_REPLY, VARLINK_CALLING) &&
-+            v->timeout != USEC_INFINITY) {
-+                if (ret)
-+                        *ret = usec_add(v->timestamp, v->timeout);
-+                return 1;
-+        } else {
-+                if (ret)
-+                        *ret = USEC_INFINITY;
-+                return 0;
-+        }
-+}
-+
-+int varlink_flush(Varlink *v) {
-+        int ret = 0, r;
-+
-+        assert_return(v, -EINVAL);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return -ENOTCONN;
-+
-+        for (;;) {
-+                struct pollfd pfd;
-+
-+                if (v->output_buffer_size == 0)
-+                        break;
-+                if (v->write_disconnected)
-+                        return -ECONNRESET;
-+
-+                r = varlink_write(v);
-+                if (r < 0)
-+                        return r;
-+                if (r > 0) {
-+                        ret = 1;
-+                        continue;
-+                }
-+
-+                pfd = (struct pollfd) {
-+                        .fd = v->fd,
-+                        .events = POLLOUT,
-+                };
-+
-+                if (poll(&pfd, 1, -1) < 0)
-+                        return -errno;
-+
-+                handle_revents(v, pfd.revents);
-+        }
-+
-+        return ret;
-+}
-+
-+static void varlink_detach_server(Varlink *v) {
-+        assert(v);
-+
-+        if (!v->server)
-+                return;
-+
-+        if (v->server->by_uid &&
-+            v->ucred_acquired &&
-+            uid_is_valid(v->ucred.uid)) {
-+                unsigned c;
-+
-+                c = PTR_TO_UINT(hashmap_get(v->server->by_uid, UID_TO_PTR(v->ucred.uid)));
-+                assert(c > 0);
-+
-+                if (c == 1)
-+                        (void) hashmap_remove(v->server->by_uid, UID_TO_PTR(v->ucred.uid));
-+                else
-+                        (void) hashmap_replace(v->server->by_uid, UID_TO_PTR(v->ucred.uid), UINT_TO_PTR(c - 1));
-+        }
-+
-+        assert(v->server->n_connections > 0);
-+        v->server->n_connections--;
-+
-+        /* If this is a connection associated to a server, then let's disconnect the server and the
-+         * connection from each other. This drops the dangling reference that connect_callback() set up. */
-+        v->server = varlink_server_unref(v->server);
-+        varlink_unref(v);
-+}
-+
-+int varlink_close(Varlink *v) {
-+
-+        assert_return(v, -EINVAL);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return 0;
-+
-+        varlink_set_state(v, VARLINK_DISCONNECTED);
-+
-+        /* Let's take a reference first, since varlink_detach_server() might drop the final (dangling) ref
-+         * which would destroy us before we can call varlink_clear() */
-+        varlink_ref(v);
-+        varlink_detach_server(v);
-+        varlink_clear(v);
-+        varlink_unref(v);
-+
-+        return 1;
-+}
-+
-+Varlink* varlink_flush_close_unref(Varlink *v) {
-+
-+        if (!v)
-+                return NULL;
-+
-+        (void) varlink_flush(v);
-+        (void) varlink_close(v);
-+
-+        return varlink_unref(v);
-+}
-+
-+static int varlink_enqueue_json(Varlink *v, JsonVariant *m) {
-+        _cleanup_free_ char *text = NULL;
-+        int r;
-+
-+        assert(v);
-+        assert(m);
-+
-+        r = json_variant_format(m, 0, &text);
-+        if (r < 0)
-+                return r;
-+
-+        if (v->output_buffer_size + r + 1 > VARLINK_BUFFER_MAX)
-+                return -ENOBUFS;
-+
-+        varlink_log(v, "Sending message: %s", text);
-+
-+        if (v->output_buffer_size == 0) {
-+
-+                free_and_replace(v->output_buffer, text);
-+
-+                v->output_buffer_size = v->output_buffer_allocated = r + 1;
-+                v->output_buffer_index = 0;
-+
-+        } else if (v->output_buffer_index == 0) {
-+
-+                if (!GREEDY_REALLOC(v->output_buffer, v->output_buffer_allocated, v->output_buffer_size + r + 1))
-+                        return -ENOMEM;
-+
-+                memcpy(v->output_buffer + v->output_buffer_size, text, r + 1);
-+                v->output_buffer_size += r + 1;
-+
-+        } else {
-+                char *n;
-+
-+                n = new(char, v->output_buffer_size + r + 1);
-+                if (!n)
-+                        return -ENOMEM;
-+
-+                memcpy(mempcpy(n, v->output_buffer + v->output_buffer_index, v->output_buffer_size), text, r + 1);
-+
-+                free_and_replace(v->output_buffer, n);
-+                v->output_buffer_size += r + 1;
-+                v->output_buffer_index = 0;
-+        }
-+
-+        return 0;
-+}
-+
-+int varlink_send(Varlink *v, const char *method, JsonVariant *parameters) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+        assert_return(method, -EINVAL);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return -ENOTCONN;
-+        if (!IN_SET(v->state, VARLINK_IDLE_CLIENT, VARLINK_AWAITING_REPLY))
-+                return -EBUSY;
-+
-+        r = varlink_sanitize_parameters(&parameters);
-+        if (r < 0)
-+                return r;
-+
-+        r = json_build(&m, JSON_BUILD_OBJECT(
-+                                       JSON_BUILD_PAIR("method", JSON_BUILD_STRING(method)),
-+                                       JSON_BUILD_PAIR("parameters", JSON_BUILD_VARIANT(parameters)),
-+                                       JSON_BUILD_PAIR("oneway", JSON_BUILD_BOOLEAN(true))));
-+        if (r < 0)
-+                return r;
-+
-+        r = varlink_enqueue_json(v, m);
-+        if (r < 0)
-+                return r;
-+
-+        /* No state change here, this is one-way only after all */
-+        v->timestamp = now(CLOCK_MONOTONIC);
-+        return 0;
-+}
-+
-+int varlink_sendb(Varlink *v, const char *method, ...) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *parameters = NULL;
-+        va_list ap;
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+
-+        va_start(ap, method);
-+        r = json_buildv(&parameters, ap);
-+        va_end(ap);
-+
-+        if (r < 0)
-+                return r;
-+
-+        return varlink_send(v, method, parameters);
-+}
-+
-+int varlink_invoke(Varlink *v, const char *method, JsonVariant *parameters) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+        assert_return(method, -EINVAL);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return -ENOTCONN;
-+        if (!IN_SET(v->state, VARLINK_IDLE_CLIENT, VARLINK_AWAITING_REPLY))
-+                return -EBUSY;
-+
-+        r = varlink_sanitize_parameters(&parameters);
-+        if (r < 0)
-+                return r;
-+
-+        r = json_build(&m, JSON_BUILD_OBJECT(
-+                                       JSON_BUILD_PAIR("method", JSON_BUILD_STRING(method)),
-+                                       JSON_BUILD_PAIR("parameters", JSON_BUILD_VARIANT(parameters))));
-+        if (r < 0)
-+                return r;
-+
-+        r = varlink_enqueue_json(v, m);
-+        if (r < 0)
-+                return r;
-+
-+        varlink_set_state(v, VARLINK_AWAITING_REPLY);
-+        v->n_pending++;
-+        v->timestamp = now(CLOCK_MONOTONIC);
-+
-+        return 0;
-+}
-+
-+int varlink_invokeb(Varlink *v, const char *method, ...) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *parameters = NULL;
-+        va_list ap;
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+
-+        va_start(ap, method);
-+        r = json_buildv(&parameters, ap);
-+        va_end(ap);
-+
-+        if (r < 0)
-+                return r;
-+
-+        return varlink_invoke(v, method, parameters);
-+}
-+
-+int varlink_call(
-+                Varlink *v,
-+                const char *method,
-+                JsonVariant *parameters,
-+                JsonVariant **ret_parameters,
-+                const char **ret_error_id,
-+                VarlinkReplyFlags *ret_flags) {
-+
-+        _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+        assert_return(method, -EINVAL);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return -ENOTCONN;
-+        if (!IN_SET(v->state, VARLINK_IDLE_CLIENT))
-+                return -EBUSY;
-+
-+        assert(v->n_pending == 0); /* n_pending can't be > 0 if we are in VARLINK_IDLE_CLIENT state */
-+
-+        r = varlink_sanitize_parameters(&parameters);
-+        if (r < 0)
-+                return r;
-+
-+        r = json_build(&m, JSON_BUILD_OBJECT(
-+                                       JSON_BUILD_PAIR("method", JSON_BUILD_STRING(method)),
-+                                       JSON_BUILD_PAIR("parameters", JSON_BUILD_VARIANT(parameters))));
-+        if (r < 0)
-+                return r;
-+
-+        r = varlink_enqueue_json(v, m);
-+        if (r < 0)
-+                return r;
-+
-+        varlink_set_state(v, VARLINK_CALLING);
-+        v->n_pending++;
-+        v->timestamp = now(CLOCK_MONOTONIC);
-+
-+        while (v->state == VARLINK_CALLING) {
-+
-+                r = varlink_process(v);
-+                if (r < 0)
-+                        return r;
-+                if (r > 0)
-+                        continue;
-+
-+                r = varlink_wait(v, USEC_INFINITY);
-+                if (r < 0)
-+                        return r;
-+        }
-+
-+        switch (v->state) {
-+
-+        case VARLINK_CALLED:
-+                assert(v->current);
-+
-+                json_variant_unref(v->reply);
-+                v->reply = TAKE_PTR(v->current);
-+
-+                varlink_set_state(v, VARLINK_IDLE_CLIENT);
-+                assert(v->n_pending == 1);
-+                v->n_pending--;
-+
-+                if (ret_parameters)
-+                        *ret_parameters = json_variant_by_key(v->reply, "parameters");
-+                if (ret_error_id)
-+                        *ret_error_id = json_variant_string(json_variant_by_key(v->reply, "error"));
-+                if (ret_flags)
-+                        *ret_flags = 0;
-+
-+                return 1;
-+
-+        case VARLINK_PENDING_DISCONNECT:
-+        case VARLINK_DISCONNECTED:
-+                return -ECONNRESET;
-+
-+        case VARLINK_PENDING_TIMEOUT:
-+                return -ETIME;
-+
-+        default:
-+                assert_not_reached("Unexpected state after method call.");
-+        }
-+}
-+
-+int varlink_callb(
-+                Varlink *v,
-+                const char *method,
-+                JsonVariant **ret_parameters,
-+                const char **ret_error_id,
-+                VarlinkReplyFlags *ret_flags, ...) {
-+
-+        _cleanup_(json_variant_unrefp) JsonVariant *parameters = NULL;
-+        va_list ap;
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+
-+        va_start(ap, ret_flags);
-+        r = json_buildv(&parameters, ap);
-+        va_end(ap);
-+
-+        if (r < 0)
-+                return r;
-+
-+        return varlink_call(v, method, parameters, ret_parameters, ret_error_id, ret_flags);
-+}
-+
-+int varlink_reply(Varlink *v, JsonVariant *parameters) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return -ENOTCONN;
-+        if (!IN_SET(v->state,
-+                    VARLINK_PROCESSING_METHOD, VARLINK_PROCESSING_METHOD_MORE,
-+                    VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE))
-+                return -EBUSY;
-+
-+        r = varlink_sanitize_parameters(&parameters);
-+        if (r < 0)
-+                return r;
-+
-+        r = json_build(&m, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("parameters", JSON_BUILD_VARIANT(parameters))));
-+        if (r < 0)
-+                return r;
-+
-+        r = varlink_enqueue_json(v, m);
-+        if (r < 0)
-+                return r;
-+
-+        if (IN_SET(v->state, VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE)) {
-+                /* We just replied to a method call that was let hanging for a while (i.e. we were outside of
-+                 * the varlink_dispatch_method() stack frame), which means with this reply we are ready to
-+                 * process further messages. */
-+                v->current = json_variant_unref(v->current);
-+                varlink_set_state(v, VARLINK_IDLE_SERVER);
-+        } else
-+                /* We replied to a method call from within the varlink_dispatch_method() stack frame), which
-+                 * means we should it handle the rest of the state engine. */
-+                varlink_set_state(v, VARLINK_PROCESSED_METHOD);
-+
-+        return 1;
-+}
-+
-+int varlink_replyb(Varlink *v, ...) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *parameters = NULL;
-+        va_list ap;
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+
-+        va_start(ap, v);
-+        r = json_buildv(&parameters, ap);
-+        va_end(ap);
-+
-+        if (r < 0)
-+                return r;
-+
-+        return varlink_reply(v, parameters);
-+}
-+
-+int varlink_error(Varlink *v, const char *error_id, JsonVariant *parameters) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+        assert_return(error_id, -EINVAL);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return -ENOTCONN;
-+        if (!IN_SET(v->state,
-+                    VARLINK_PROCESSING_METHOD, VARLINK_PROCESSING_METHOD_MORE,
-+                    VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE))
-+                return -EBUSY;
-+
-+        r = varlink_sanitize_parameters(&parameters);
-+        if (r < 0)
-+                return r;
-+
-+        r = json_build(&m, JSON_BUILD_OBJECT(
-+                                       JSON_BUILD_PAIR("error", JSON_BUILD_STRING(error_id)),
-+                                       JSON_BUILD_PAIR("parameters", JSON_BUILD_VARIANT(parameters))));
-+        if (r < 0)
-+                return r;
-+
-+        r = varlink_enqueue_json(v, m);
-+        if (r < 0)
-+                return r;
-+
-+        if (IN_SET(v->state, VARLINK_PENDING_METHOD, VARLINK_PENDING_METHOD_MORE)) {
-+                v->current = json_variant_unref(v->current);
-+                varlink_set_state(v, VARLINK_IDLE_SERVER);
-+        } else
-+                varlink_set_state(v, VARLINK_PROCESSED_METHOD);
-+
-+        return 1;
-+}
-+
-+int varlink_errorb(Varlink *v, const char *error_id, ...) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *parameters = NULL;
-+        va_list ap;
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+        assert_return(error_id, -EINVAL);
-+
-+        va_start(ap, error_id);
-+        r = json_buildv(&parameters, ap);
-+        va_end(ap);
-+
-+        if (r < 0)
-+                return r;
-+
-+        return varlink_error(v, error_id, parameters);
-+}
-+
-+int varlink_error_invalid_parameter(Varlink *v, JsonVariant *parameters) {
-+
-+        assert_return(v, -EINVAL);
-+        assert_return(parameters, -EINVAL);
-+
-+        /* We expect to be called in one of two ways: the 'parameters' argument is a string variant in which
-+         * case it is the parameter key name that is invalid. Or the 'parameters' argument is an object
-+         * variant in which case we'll pull out the first key. The latter mode is useful in functions that
-+         * don't expect any arguments. */
-+
-+        if (json_variant_is_string(parameters))
-+                return varlink_error(v, VARLINK_ERROR_INVALID_PARAMETER, parameters);
-+
-+        if (json_variant_is_object(parameters) &&
-+            json_variant_elements(parameters) > 0)
-+                return varlink_error(v, VARLINK_ERROR_INVALID_PARAMETER,
-+                                     json_variant_by_index(parameters, 0));
-+
-+        return -EINVAL;
-+}
-+
-+int varlink_notify(Varlink *v, JsonVariant *parameters) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *m = NULL;
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+
-+        if (v->state == VARLINK_DISCONNECTED)
-+                return -ENOTCONN;
-+        if (!IN_SET(v->state, VARLINK_PROCESSING_METHOD_MORE, VARLINK_PENDING_METHOD_MORE))
-+                return -EBUSY;
-+
-+        r = varlink_sanitize_parameters(&parameters);
-+        if (r < 0)
-+                return r;
-+
-+        r = json_build(&m, JSON_BUILD_OBJECT(
-+                                       JSON_BUILD_PAIR("parameters", JSON_BUILD_VARIANT(parameters)),
-+                                       JSON_BUILD_PAIR("continues", JSON_BUILD_BOOLEAN(true))));
-+        if (r < 0)
-+                return r;
-+
-+        r = varlink_enqueue_json(v, m);
-+        if (r < 0)
-+                return r;
-+
-+        /* No state change, as more is coming */
-+        return 1;
-+}
-+
-+int varlink_notifyb(Varlink *v, ...) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *parameters = NULL;
-+        va_list ap;
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+
-+        va_start(ap, v);
-+        r = json_buildv(&parameters, ap);
-+        va_end(ap);
-+
-+        if (r < 0)
-+                return r;
-+
-+        return varlink_notify(v, parameters);
-+}
-+
-+int varlink_bind_reply(Varlink *v, VarlinkReply callback) {
-+        assert_return(v, -EINVAL);
-+
-+        if (callback && v->reply_callback && callback != v->reply_callback)
-+                return -EBUSY;
-+
-+        v->reply_callback = callback;
-+
-+        return 0;
-+}
-+
-+void* varlink_set_userdata(Varlink *v, void *userdata) {
-+        void *old;
-+
-+        assert_return(v, NULL);
-+
-+        old = v->userdata;
-+        v->userdata = userdata;
-+
-+        return old;
-+}
-+
-+void* varlink_get_userdata(Varlink *v) {
-+        assert_return(v, NULL);
-+
-+        return v->userdata;
-+}
-+
-+static int varlink_acquire_ucred(Varlink *v) {
-+        int r;
-+
-+        assert(v);
-+
-+        if (v->ucred_acquired)
-+                return 0;
-+
-+        r = getpeercred(v->fd, &v->ucred);
-+        if (r < 0)
-+                return r;
-+
-+        v->ucred_acquired = true;
-+        return 0;
-+}
-+
-+int varlink_get_peer_uid(Varlink *v, uid_t *ret) {
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+        assert_return(ret, -EINVAL);
-+
-+        r = varlink_acquire_ucred(v);
-+        if (r < 0)
-+                return r;
-+
-+        if (!uid_is_valid(v->ucred.uid))
-+                return -ENODATA;
-+
-+        *ret = v->ucred.uid;
-+        return 0;
-+}
-+
-+int varlink_get_peer_pid(Varlink *v, pid_t *ret) {
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+        assert_return(ret, -EINVAL);
-+
-+        r = varlink_acquire_ucred(v);
-+        if (r < 0)
-+                return r;
-+
-+        if (!pid_is_valid(v->ucred.pid))
-+                return -ENODATA;
-+
-+        *ret = v->ucred.pid;
-+        return 0;
-+}
-+
-+int varlink_set_relative_timeout(Varlink *v, usec_t timeout) {
-+        assert_return(v, -EINVAL);
-+        assert_return(timeout > 0, -EINVAL);
-+
-+        v->timeout = timeout;
-+        return 0;
-+}
-+
-+VarlinkServer *varlink_get_server(Varlink *v) {
-+        assert_return(v, NULL);
-+
-+        return v->server;
-+}
-+
-+int varlink_set_description(Varlink *v, const char *description) {
-+        assert_return(v, -EINVAL);
-+
-+        return free_and_strdup(&v->description, description);
-+}
-+
-+static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
-+        Varlink *v = userdata;
-+
-+        assert(s);
-+        assert(v);
-+
-+        handle_revents(v, revents);
-+        (void) varlink_process(v);
-+
-+        return 1;
-+}
-+
-+static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
-+        Varlink *v = userdata;
-+
-+        assert(s);
-+        assert(v);
-+
-+        (void) varlink_process(v);
-+        return 1;
-+}
-+
-+static int defer_callback(sd_event_source *s, void *userdata) {
-+        Varlink *v = userdata;
-+
-+        assert(s);
-+        assert(v);
-+
-+        (void) varlink_process(v);
-+        return 1;
-+}
-+
-+static int prepare_callback(sd_event_source *s, void *userdata) {
-+        Varlink *v = userdata;
-+        int r, e;
-+        usec_t until;
-+
-+        assert(s);
-+        assert(v);
-+
-+        e = varlink_get_events(v);
-+        if (e < 0)
-+                return e;
-+
-+        r = sd_event_source_set_io_events(v->io_event_source, e);
-+        if (r < 0)
-+                return r;
-+
-+        r = varlink_get_timeout(v, &until);
-+        if (r < 0)
-+                return r;
-+        if (r > 0) {
-+                r = sd_event_source_set_time(v->time_event_source, until);
-+                if (r < 0)
-+                        return r;
-+        }
-+
-+        r = sd_event_source_set_enabled(v->time_event_source, r > 0 ? SD_EVENT_ON : SD_EVENT_OFF);
-+        if (r < 0)
-+                return r;
-+
-+        return 1;
-+}
-+
-+static int quit_callback(sd_event_source *event, void *userdata) {
-+        Varlink *v = userdata;
-+
-+        assert(event);
-+        assert(v);
-+
-+        varlink_flush(v);
-+        varlink_close(v);
-+
-+        return 1;
-+}
-+
-+int varlink_attach_event(Varlink *v, sd_event *e, int64_t priority) {
-+        int r;
-+
-+        assert_return(v, -EINVAL);
-+        assert_return(!v->event, -EBUSY);
-+
-+        if (e)
-+                v->event = sd_event_ref(e);
-+        else {
-+                r = sd_event_default(&v->event);
-+                if (r < 0)
-+                        return r;
-+        }
-+
-+        r = sd_event_add_time(v->event, &v->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, v);
-+        if (r < 0)
-+                goto fail;
-+
-+        r = sd_event_source_set_priority(v->time_event_source, priority);
-+        if (r < 0)
-+                goto fail;
-+
-+        (void) sd_event_source_set_description(v->time_event_source, "varlink-time");
-+
-+        r = sd_event_add_exit(v->event, &v->quit_event_source, quit_callback, v);
-+        if (r < 0)
-+                goto fail;
-+
-+        r = sd_event_source_set_priority(v->quit_event_source, priority);
-+        if (r < 0)
-+                goto fail;
-+
-+        (void) sd_event_source_set_description(v->quit_event_source, "varlink-quit");
-+
-+        r = sd_event_add_io(v->event, &v->io_event_source, v->fd, 0, io_callback, v);
-+        if (r < 0)
-+                goto fail;
-+
-+        r = sd_event_source_set_prepare(v->io_event_source, prepare_callback);
-+        if (r < 0)
-+                goto fail;
-+
-+        r = sd_event_source_set_priority(v->io_event_source, priority);
-+        if (r < 0)
-+                goto fail;
-+
-+        (void) sd_event_source_set_description(v->io_event_source, "varlink-io");
-+
-+        r = sd_event_add_defer(v->event, &v->defer_event_source, defer_callback, v);
-+        if (r < 0)
-+                goto fail;
-+
-+        r = sd_event_source_set_priority(v->defer_event_source, priority);
-+        if (r < 0)
-+                goto fail;
-+
-+        (void) sd_event_source_set_description(v->defer_event_source, "varlink-defer");
-+
-+        return 0;
-+
-+fail:
-+        varlink_detach_event(v);
-+        return r;
-+}
-+
-+
-+void varlink_detach_event(Varlink *v) {
-+        if (!v)
-+                return;
-+
-+        varlink_detach_event_sources(v);
-+
-+        v->event = sd_event_unref(v->event);
-+}
-+
-+sd_event *varlink_get_event(Varlink *v) {
-+        assert_return(v, NULL);
-+
-+        return v->event;
-+}
-+
-+int varlink_server_new(VarlinkServer **ret, VarlinkServerFlags flags) {
-+        VarlinkServer *s;
-+
-+        assert_return(ret, -EINVAL);
-+        assert_return((flags & ~_VARLINK_SERVER_FLAGS_ALL) == 0, -EINVAL);
-+
-+        s = new(VarlinkServer, 1);
-+        if (!s)
-+                return -ENOMEM;
-+
-+        *s = (VarlinkServer) {
-+                .n_ref = 1,
-+                .flags = flags,
-+                .connections_max = varlink_server_connections_max(NULL),
-+                .connections_per_uid_max = varlink_server_connections_per_uid_max(NULL),
-+        };
-+
-+        *ret = s;
-+        return 0;
-+}
-+
-+static VarlinkServer* varlink_server_destroy(VarlinkServer *s) {
-+        char *m;
-+
-+        if (!s)
-+                return NULL;
-+
-+        varlink_server_shutdown(s);
-+
-+        while ((m = hashmap_steal_first_key(s->methods)))
-+                free(m);
-+
-+        hashmap_free(s->methods);
-+        hashmap_free(s->by_uid);
-+
-+        sd_event_unref(s->event);
-+
-+        free(s->description);
-+
-+        return mfree(s);
-+}
-+
-+DEFINE_TRIVIAL_REF_UNREF_FUNC(VarlinkServer, varlink_server, varlink_server_destroy);
-+
-+static int validate_connection(VarlinkServer *server, const struct ucred *ucred) {
-+        int allowed = -1;
-+
-+        assert(server);
-+        assert(ucred);
-+
-+        if (FLAGS_SET(server->flags, VARLINK_SERVER_ROOT_ONLY))
-+                allowed = ucred->uid == 0;
-+
-+        if (FLAGS_SET(server->flags, VARLINK_SERVER_MYSELF_ONLY))
-+                allowed = allowed > 0 || ucred->uid == getuid();
-+
-+        if (allowed == 0) { /* Allow access when it is explicitly allowed or when neither
-+                             * VARLINK_SERVER_ROOT_ONLY nor VARLINK_SERVER_MYSELF_ONLY are specified. */
-+                varlink_server_log(server, "Unprivileged client attempted connection, refusing.");
-+                return 0;
-+        }
-+
-+        if (server->n_connections >= server->connections_max) {
-+                varlink_server_log(server, "Connection limit of %u reached, refusing.", server->connections_max);
-+                return 0;
-+        }
-+
-+        if (FLAGS_SET(server->flags, VARLINK_SERVER_ACCOUNT_UID)) {
-+                unsigned c;
-+
-+                if (!uid_is_valid(ucred->uid)) {
-+                        varlink_server_log(server, "Client with invalid UID attempted connection, refusing.");
-+                        return 0;
-+                }
-+
-+                c = PTR_TO_UINT(hashmap_get(server->by_uid, UID_TO_PTR(ucred->uid)));
-+                if (c >= server->connections_per_uid_max) {
-+                        varlink_server_log(server, "Per-UID connection limit of %u reached, refusing.",
-+                                           server->connections_per_uid_max);
-+                        return 0;
-+                }
-+        }
-+
-+        return 1;
-+}
-+
-+static int count_connection(VarlinkServer *server, struct ucred *ucred) {
-+        unsigned c;
-+        int r;
-+
-+        assert(server);
-+        assert(ucred);
-+
-+        server->n_connections++;
-+
-+        if (FLAGS_SET(server->flags, VARLINK_SERVER_ACCOUNT_UID)) {
-+                r = hashmap_ensure_allocated(&server->by_uid, NULL);
-+                if (r < 0)
-+                        return log_debug_errno(r, "Failed to allocate UID hash table: %m");
-+
-+                c = PTR_TO_UINT(hashmap_get(server->by_uid, UID_TO_PTR(ucred->uid)));
-+
-+                varlink_server_log(server, "Connections of user " UID_FMT ": %u (of %u max)",
-+                                   ucred->uid, c, server->connections_per_uid_max);
-+
-+                r = hashmap_replace(server->by_uid, UID_TO_PTR(ucred->uid), UINT_TO_PTR(c + 1));
-+                if (r < 0)
-+                        return log_debug_errno(r, "Failed to increment counter in UID hash table: %m");
-+        }
-+
-+        return 0;
-+}
-+
-+int varlink_server_add_connection(VarlinkServer *server, int fd, Varlink **ret) {
-+        _cleanup_(varlink_unrefp) Varlink *v = NULL;
-+        bool ucred_acquired;
-+        struct ucred ucred;
-+        int r;
-+
-+        assert_return(server, -EINVAL);
-+        assert_return(fd >= 0, -EBADF);
-+
-+        if ((server->flags & (VARLINK_SERVER_ROOT_ONLY|VARLINK_SERVER_ACCOUNT_UID)) != 0) {
-+                r = getpeercred(fd, &ucred);
-+                if (r < 0)
-+                        return varlink_server_log_errno(server, r, "Failed to acquire peer credentials of incoming socket, refusing: %m");
-+
-+                ucred_acquired = true;
-+
-+                r = validate_connection(server, &ucred);
-+                if (r < 0)
-+                        return r;
-+                if (r == 0)
-+                        return -EPERM;
-+        } else
-+                ucred_acquired = false;
-+
-+        r = varlink_new(&v);
-+        if (r < 0)
-+                return varlink_server_log_errno(server, r, "Failed to allocate connection object: %m");
-+
-+        r = count_connection(server, &ucred);
-+        if (r < 0)
-+                return r;
-+
-+        v->fd = fd;
-+        v->userdata = server->userdata;
-+        if (ucred_acquired) {
-+                v->ucred = ucred;
-+                v->ucred_acquired = true;
-+        }
-+
-+        (void) asprintf(&v->description, "%s-%i", server->description ?: "varlink", v->fd);
-+
-+        /* Link up the server and the connection, and take reference in both directions. Note that the
-+         * reference on the connection is left dangling. It will be dropped when the connection is closed,
-+         * which happens in varlink_close(), including in the event loop quit callback. */
-+        v->server = varlink_server_ref(server);
-+        varlink_ref(v);
-+
-+        varlink_set_state(v, VARLINK_IDLE_SERVER);
-+
-+        r = varlink_attach_event(v, server->event, server->event_priority);
-+        if (r < 0) {
-+                varlink_log_errno(v, r, "Failed to attach new connection: %m");
-+                v->fd = -1; /* take the fd out of the connection again */
-+                varlink_close(v);
-+                return r;
-+        }
-+
-+        if (ret)
-+                *ret = v;
-+
-+        return 0;
-+}
-+
-+static int connect_callback(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
-+        VarlinkServerSocket *ss = userdata;
-+        _cleanup_close_ int cfd = -1;
-+        Varlink *v = NULL;
-+        int r;
-+
-+        assert(source);
-+        assert(ss);
-+
-+        varlink_server_log(ss->server, "New incoming connection.");
-+
-+        cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
-+        if (cfd < 0) {
-+                if (ERRNO_IS_ACCEPT_AGAIN(errno))
-+                        return 0;
-+
-+                return varlink_server_log_errno(ss->server, errno, "Failed to accept incoming socket: %m");
-+        }
-+
-+        r = varlink_server_add_connection(ss->server, cfd, &v);
-+        if (r < 0)
-+                return 0;
-+
-+        TAKE_FD(cfd);
-+
-+        if (ss->server->connect_callback) {
-+                r = ss->server->connect_callback(ss->server, v, ss->server->userdata);
-+                if (r < 0) {
-+                        varlink_log_errno(v, r, "Connection callback returned error, disconnecting client: %m");
-+                        varlink_close(v);
-+                        return 0;
-+                }
-+        }
-+
-+        return 0;
-+}
-+
-+int varlink_server_listen_fd(VarlinkServer *s, int fd) {
-+        _cleanup_free_ VarlinkServerSocket *ss = NULL;
-+        int r;
-+
-+        assert_return(s, -EINVAL);
-+        assert_return(fd >= 0, -EBADF);
-+
-+        r = fd_nonblock(fd, true);
-+        if (r < 0)
-+                return r;
-+
-+        ss = new(VarlinkServerSocket, 1);
-+        if (!ss)
-+                return -ENOMEM;
-+
-+        *ss = (VarlinkServerSocket) {
-+                .server = s,
-+                .fd = fd,
-+        };
-+
-+        if (s->event) {
-+                _cleanup_(sd_event_source_unrefp) sd_event_source *es = NULL;
-+
-+                r = sd_event_add_io(s->event, &es, fd, EPOLLIN, connect_callback, ss);
-+                if (r < 0)
-+                        return r;
-+
-+                r = sd_event_source_set_priority(ss->event_source, s->event_priority);
-+                if (r < 0)
-+                        return r;
-+        }
-+
-+        LIST_PREPEND(sockets, s->sockets, TAKE_PTR(ss));
-+        return 0;
-+}
-+
-+int varlink_server_listen_address(VarlinkServer *s, const char *address, mode_t m) {
-+        union sockaddr_union sockaddr;
-+        _cleanup_close_ int fd = -1;
-+        int r;
-+
-+        assert_return(s, -EINVAL);
-+        assert_return(address, -EINVAL);
-+        assert_return((m & ~0777) == 0, -EINVAL);
-+
-+        r = sockaddr_un_set_path(&sockaddr.un, address);
-+        if (r < 0)
-+                return r;
-+
-+        fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
-+        if (fd < 0)
-+                return -errno;
-+
-+        (void) sockaddr_un_unlink(&sockaddr.un);
-+
-+        RUN_WITH_UMASK(~m & 0777)
-+                if (bind(fd, &sockaddr.sa, SOCKADDR_UN_LEN(sockaddr.un)) < 0)
-+                        return -errno;
-+
-+        if (listen(fd, SOMAXCONN) < 0)
-+                return -errno;
-+
-+        r = varlink_server_listen_fd(s, fd);
-+        if (r < 0)
-+                return r;
-+
-+        TAKE_FD(fd);
-+        return 0;
-+}
-+
-+void* varlink_server_set_userdata(VarlinkServer *s, void *userdata) {
-+        void *ret;
-+
-+        assert_return(s, NULL);
-+
-+        ret = s->userdata;
-+        s->userdata = userdata;
-+
-+        return ret;
-+}
-+
-+void* varlink_server_get_userdata(VarlinkServer *s) {
-+        assert_return(s, NULL);
-+
-+        return s->userdata;
-+}
-+
-+static VarlinkServerSocket* varlink_server_socket_destroy(VarlinkServerSocket *ss) {
-+        if (!ss)
-+                return NULL;
-+
-+        if (ss->server)
-+                LIST_REMOVE(sockets, ss->server->sockets, ss);
-+
-+        if (ss->event_source) {
-+                (void) sd_event_source_set_enabled(ss->event_source, SD_EVENT_OFF);
-+                sd_event_source_unref(ss->event_source);
-+        }
-+
-+        free(ss->address);
-+        safe_close(ss->fd);
-+
-+        return mfree(ss);
-+}
-+
-+int varlink_server_shutdown(VarlinkServer *s) {
-+        assert_return(s, -EINVAL);
-+
-+        while (s->sockets)
-+                varlink_server_socket_destroy(s->sockets);
-+
-+        return 0;
-+}
-+
-+int varlink_server_attach_event(VarlinkServer *s, sd_event *e, int64_t priority) {
-+        VarlinkServerSocket *ss;
-+        int r;
-+
-+        assert_return(s, -EINVAL);
-+        assert_return(!s->event, -EBUSY);
-+
-+        if (e)
-+                s->event = sd_event_ref(e);
-+        else {
-+                r = sd_event_default(&s->event);
-+                if (r < 0)
-+                        return r;
-+        }
-+
-+        LIST_FOREACH(sockets, ss, s->sockets) {
-+                assert(!ss->event_source);
-+
-+                r = sd_event_add_io(s->event, &ss->event_source, ss->fd, EPOLLIN, connect_callback, ss);
-+                if (r < 0)
-+                        goto fail;
-+
-+                r = sd_event_source_set_priority(ss->event_source, priority);
-+                if (r < 0)
-+                        goto fail;
-+        }
-+
-+        s->event_priority = priority;
-+        return 0;
-+
-+fail:
-+        varlink_server_detach_event(s);
-+        return r;
-+}
-+
-+int varlink_server_detach_event(VarlinkServer *s) {
-+        VarlinkServerSocket *ss;
-+
-+        assert_return(s, -EINVAL);
-+
-+        LIST_FOREACH(sockets, ss, s->sockets) {
-+
-+                if (!ss->event_source)
-+                        continue;
-+
-+                (void) sd_event_source_set_enabled(ss->event_source, SD_EVENT_OFF);
-+                ss->event_source = sd_event_source_unref(ss->event_source);
-+        }
-+
-+        sd_event_unref(s->event);
-+        return 0;
-+}
-+
-+sd_event *varlink_server_get_event(VarlinkServer *s) {
-+        assert_return(s, NULL);
-+
-+        return s->event;
-+}
-+
-+int varlink_server_bind_method(VarlinkServer *s, const char *method, VarlinkMethod callback) {
-+        char *m;
-+        int r;
-+
-+        assert_return(s, -EINVAL);
-+        assert_return(method, -EINVAL);
-+        assert_return(callback, -EINVAL);
-+
-+        if (startswith(method, "org.varlink.service."))
-+                return -EEXIST;
-+
-+        r = hashmap_ensure_allocated(&s->methods, &string_hash_ops);
-+        if (r < 0)
-+                return r;
-+
-+        m = strdup(method);
-+        if (!m)
-+                return -ENOMEM;
-+
-+        r = hashmap_put(s->methods, m, callback);
-+        if (r < 0) {
-+                free(m);
-+                return r;
-+        }
-+
-+        return 0;
-+}
-+
-+int varlink_server_bind_method_many_internal(VarlinkServer *s, ...) {
-+        va_list ap;
-+        int r;
-+
-+        assert_return(s, -EINVAL);
-+
-+        va_start(ap, s);
-+        for (;;) {
-+                VarlinkMethod callback;
-+                const char *method;
-+
-+                method = va_arg(ap, const char *);
-+                if (!method)
-+                        break;
-+
-+                callback = va_arg(ap, VarlinkMethod);
-+
-+                r = varlink_server_bind_method(s, method, callback);
-+                if (r < 0)
-+                        return r;
-+        }
-+
-+        return 0;
-+}
-+
-+int varlink_server_bind_connect(VarlinkServer *s, VarlinkConnect callback) {
-+        assert_return(s, -EINVAL);
-+
-+        if (callback && s->connect_callback && callback != s->connect_callback)
-+                return -EBUSY;
-+
-+        s->connect_callback = callback;
-+        return 0;
-+}
-+
-+unsigned varlink_server_connections_max(VarlinkServer *s) {
-+        struct rlimit rl;
-+
-+        /* If a server is specified, return the setting for that server, otherwise the default value */
-+        if (s)
-+                return s->connections_max;
-+
-+        assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
-+
-+        /* Make sure we never use up more than ¾th of RLIMIT_NOFILE for IPC */
-+        if (VARLINK_DEFAULT_CONNECTIONS_MAX > rl.rlim_cur / 4 * 3)
-+                return rl.rlim_cur / 4 * 3;
-+
-+        return VARLINK_DEFAULT_CONNECTIONS_MAX;
-+}
-+
-+unsigned varlink_server_connections_per_uid_max(VarlinkServer *s) {
-+        unsigned m;
-+
-+        if (s)
-+                return s->connections_per_uid_max;
-+
-+        /* Make sure to never use up more than ¾th of available connections for a single user */
-+        m = varlink_server_connections_max(NULL);
-+        if (VARLINK_DEFAULT_CONNECTIONS_PER_UID_MAX > m)
-+                return m / 4 * 3;
-+
-+        return VARLINK_DEFAULT_CONNECTIONS_PER_UID_MAX;
-+}
-+
-+int varlink_server_set_connections_per_uid_max(VarlinkServer *s, unsigned m) {
-+        assert_return(s, -EINVAL);
-+        assert_return(m > 0, -EINVAL);
-+
-+        s->connections_per_uid_max = m;
-+        return 0;
-+}
-+
-+int varlink_server_set_connections_max(VarlinkServer *s, unsigned m) {
-+        assert_return(s, -EINVAL);
-+        assert_return(m > 0, -EINVAL);
-+
-+        s->connections_max = m;
-+        return 0;
-+}
-+
-+int varlink_server_set_description(VarlinkServer *s, const char *description) {
-+        assert_return(s, -EINVAL);
-+
-+        return free_and_strdup(&s->description, description);
-+}
-diff --git a/src/shared/varlink.h b/src/shared/varlink.h
-new file mode 100644
-index 0000000..d96fa93
---- /dev/null
-+++ b/src/shared/varlink.h
-@@ -0,0 +1,162 @@
-+/* SPDX-License-Identifier: LGPL-2.1+ */
-+#pragma once
-+
-+#include "sd-event.h"
-+
-+#include "json.h"
-+#include "time-util.h"
-+
-+/* A minimal Varlink implementation. We only implement the minimal, obvious bits here though. No validation,
-+ * no introspection, no name service, just the stuff actually needed.
-+ *
-+ * You might wonder why we aren't using libvarlink here? Varlink is a very simple protocol, which allows us
-+ * to write our own implementation relatively easily. However, the main reasons are these:
-+ *
-+ * • We want to use our own JSON subsystem, with all the benefits that brings (i.e. accurate unsigned+signed
-+ *   64bit integers, full fuzzing, logging during parsing and so on). If we'd want to use that with
-+ *   libvarlink we'd have to serialize and deserialize all the time from its own representation which is
-+ *   inefficient and nasty.
-+ *
-+ * • We want integration into sd-event, but also synchronous event-loop-less operation
-+ *
-+ * • We need proper per-UID accounting and access control, since we want to allow communication between
-+ *   unprivileged clients and privileged servers.
-+ *
-+ * • And of course, we don't want the name service and introspection stuff for now (though that might
-+ *   change).
-+ */
-+
-+typedef struct Varlink Varlink;
-+typedef struct VarlinkServer VarlinkServer;
-+
-+typedef enum VarlinkReplyFlags {
-+        VARLINK_REPLY_ERROR     = 1 << 0,
-+        VARLINK_REPLY_CONTINUES = 1 << 1,
-+        VARLINK_REPLY_LOCAL     = 1 << 2,
-+} VarlinkReplyFlags;
-+
-+typedef enum VarlinkMethodFlags {
-+        VARLINK_METHOD_ONEWAY = 1 << 0,
-+        VARLINK_METHOD_MORE   = 2 << 1,
-+} VarlinkMethodFlags;
-+
-+typedef enum VarlinkServerFlags {
-+        VARLINK_SERVER_ROOT_ONLY   = 1 << 0, /* Only accessible by root */
-+        VARLINK_SERVER_MYSELF_ONLY = 1 << 1, /* Only accessible by our own UID */
-+        VARLINK_SERVER_ACCOUNT_UID = 1 << 2, /* Do per user accounting */
-+
-+        _VARLINK_SERVER_FLAGS_ALL = (1 << 3) - 1,
-+} VarlinkServerFlags;
-+
-+typedef int (*VarlinkMethod)(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata);
-+typedef int (*VarlinkReply)(Varlink *link, JsonVariant *parameters, const char *error_id, VarlinkReplyFlags flags, void *userdata);
-+typedef int (*VarlinkConnect)(VarlinkServer *server, Varlink *link, void *userdata);
-+
-+int varlink_connect_address(Varlink **ret, const char *address);
-+int varlink_connect_fd(Varlink **ret, int fd);
-+
-+Varlink* varlink_ref(Varlink *link);
-+Varlink* varlink_unref(Varlink *v);
-+
-+int varlink_get_fd(Varlink *v);
-+int varlink_get_events(Varlink *v);
-+int varlink_get_timeout(Varlink *v, usec_t *ret);
-+
-+int varlink_attach_event(Varlink *v, sd_event *e, int64_t priority);
-+void varlink_detach_event(Varlink *v);
-+sd_event *varlink_get_event(Varlink *v);
-+
-+int varlink_process(Varlink *v);
-+int varlink_wait(Varlink *v, usec_t timeout);
-+
-+int varlink_flush(Varlink *v);
-+int varlink_close(Varlink *v);
-+
-+Varlink* varlink_flush_close_unref(Varlink *v);
-+
-+/* Enqueue method call, not expecting a reply */
-+int varlink_send(Varlink *v, const char *method, JsonVariant *parameters);
-+int varlink_sendb(Varlink *v, const char *method, ...);
-+
-+/* Send method call and wait for reply */
-+int varlink_call(Varlink *v, const char *method, JsonVariant *parameters, JsonVariant **ret_parameters, const char **ret_error_id, VarlinkReplyFlags *ret_flags);
-+int varlink_callb(Varlink *v, const char *method, JsonVariant **ret_parameters, const char **ret_error_id, VarlinkReplyFlags *ret_flags, ...);
-+
-+/* Enqueue method call, expect a reply, which is eventually delivered to the reply callback */
-+int varlink_invoke(Varlink *v, const char *method, JsonVariant *parameters);
-+int varlink_invokeb(Varlink *v, const char *method, ...);
-+
-+/* Enqueue a final reply */
-+int varlink_reply(Varlink *v, JsonVariant *parameters);
-+int varlink_replyb(Varlink *v, ...);
-+
-+/* Enqueue a (final) error */
-+int varlink_error(Varlink *v, const char *error_id, JsonVariant *parameters);
-+int varlink_errorb(Varlink *v, const char *error_id, ...);
-+int varlink_error_invalid_parameter(Varlink *v, JsonVariant *parameters);
-+
-+/* Enqueue a "more" reply */
-+int varlink_notify(Varlink *v, JsonVariant *parameters);
-+int varlink_notifyb(Varlink *v, ...);
-+
-+/* Bind a disconnect, reply or timeout callback */
-+int varlink_bind_reply(Varlink *v, VarlinkReply reply);
-+
-+void* varlink_set_userdata(Varlink *v, void *userdata);
-+void* varlink_get_userdata(Varlink *v);
-+
-+int varlink_get_peer_uid(Varlink *v, uid_t *ret);
-+int varlink_get_peer_pid(Varlink *v, pid_t *ret);
-+
-+int varlink_set_relative_timeout(Varlink *v, usec_t usec);
-+
-+VarlinkServer* varlink_get_server(Varlink *v);
-+
-+int varlink_set_description(Varlink *v, const char *d);
-+
-+/* Create a varlink server */
-+int varlink_server_new(VarlinkServer **ret, VarlinkServerFlags flags);
-+VarlinkServer *varlink_server_ref(VarlinkServer *s);
-+VarlinkServer *varlink_server_unref(VarlinkServer *s);
-+
-+/* Add addresses or fds to listen on */
-+int varlink_server_listen_address(VarlinkServer *s, const char *address, mode_t mode);
-+int varlink_server_listen_fd(VarlinkServer *s, int fd);
-+int varlink_server_add_connection(VarlinkServer *s, int fd, Varlink **ret);
-+
-+/* Bind callbacks */
-+int varlink_server_bind_method(VarlinkServer *s, const char *method, VarlinkMethod callback);
-+int varlink_server_bind_method_many_internal(VarlinkServer *s, ...);
-+#define varlink_server_bind_method_many(s, ...) varlink_server_bind_method_many_internal(s, __VA_ARGS__, NULL)
-+int varlink_server_bind_connect(VarlinkServer *s, VarlinkConnect connect);
-+
-+void* varlink_server_set_userdata(VarlinkServer *s, void *userdata);
-+void* varlink_server_get_userdata(VarlinkServer *s);
-+
-+int varlink_server_attach_event(VarlinkServer *v, sd_event *e, int64_t priority);
-+int varlink_server_detach_event(VarlinkServer *v);
-+sd_event *varlink_server_get_event(VarlinkServer *v);
-+
-+int varlink_server_shutdown(VarlinkServer *server);
-+
-+unsigned varlink_server_connections_max(VarlinkServer *s);
-+unsigned varlink_server_connections_per_uid_max(VarlinkServer *s);
-+
-+int varlink_server_set_connections_per_uid_max(VarlinkServer *s, unsigned m);
-+int varlink_server_set_connections_max(VarlinkServer *s, unsigned m);
-+
-+int varlink_server_set_description(VarlinkServer *s, const char *description);
-+
-+DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_unref);
-+DEFINE_TRIVIAL_CLEANUP_FUNC(Varlink *, varlink_flush_close_unref);
-+DEFINE_TRIVIAL_CLEANUP_FUNC(VarlinkServer *, varlink_server_unref);
-+
-+#define VARLINK_ERROR_DISCONNECTED "io.systemd.Disconnected"
-+#define VARLINK_ERROR_TIMEOUT "io.systemd.TimedOut"
-+#define VARLINK_ERROR_PROTOCOL "io.systemd.Protocol"
-+#define VARLINK_ERROR_SYSTEM "io.systemd.System"
-+
-+#define VARLINK_ERROR_INTERFACE_NOT_FOUND "org.varlink.service.InterfaceNotFound"
-+#define VARLINK_ERROR_METHOD_NOT_FOUND "org.varlink.service.MethodNotFound"
-+#define VARLINK_ERROR_METHOD_NOT_IMPLEMENTED "org.varlink.service.MethodNotImplemented"
-+#define VARLINK_ERROR_INVALID_PARAMETER "org.varlink.service.InvalidParameter"
diff --git a/debian/patches/apertis/tests-add-varlink-test.patch b/debian/patches/apertis/tests-add-varlink-test.patch
deleted file mode 100644
index 021084f06bea7419488645f050d65a070f10ae4d..0000000000000000000000000000000000000000
--- a/debian/patches/apertis/tests-add-varlink-test.patch
+++ /dev/null
@@ -1,272 +0,0 @@
-From: Lennart Poettering <lennart@poettering.net>
-Date: Thu, 11 Apr 2019 18:47:10 +0200
-Subject: tests: add varlink test
-
-Signed-off-by: Martyn Welch <martyn.welch@collabora.com>
-[Martyn Welch: Backported to systemd v241]
----
- src/test/meson.build    |   4 +
- src/test/test-varlink.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 243 insertions(+)
- create mode 100644 src/test/test-varlink.c
-
-diff --git a/src/test/meson.build b/src/test/meson.build
-index 40154cf..9a50dc4 100644
---- a/src/test/meson.build
-+++ b/src/test/meson.build
-@@ -567,6 +567,10 @@ tests += [
-           libmount,
-           libblkid]],
- 
-+        [['src/test/test-varlink.c'],
-+         [],
-+         [threads]],
-+
-         [['src/test/test-cgroup-util.c'],
-          [],
-          []],
-diff --git a/src/test/test-varlink.c b/src/test/test-varlink.c
-new file mode 100644
-index 0000000..fbfc72c
---- /dev/null
-+++ b/src/test/test-varlink.c
-@@ -0,0 +1,239 @@
-+/* SPDX-License-Identifier: LGPL-2.1+ */
-+
-+#include <fcntl.h>
-+#include <poll.h>
-+#include <pthread.h>
-+
-+#include "sd-event.h"
-+
-+#include "fd-util.h"
-+#include "json.h"
-+#include "rm-rf.h"
-+#include "strv.h"
-+#include "tmpfile-util.h"
-+#include "user-util.h"
-+#include "varlink.h"
-+
-+/* Let's pick some high value, that is higher than the largest listen() backlog, but leaves enough room below
-+   the typical RLIMIT_NOFILE value of 1024 so that we can process both sides of each socket in our
-+   process. Or in other words: "OVERLOAD_CONNECTIONS * 2 + x < 1024" should hold, for some small x that
-+   should cover any auxiliary fds, the listener server fds, stdin/stdout/stderr and whatever else. */
-+#define OVERLOAD_CONNECTIONS 333
-+
-+static int n_done = 0;
-+static int block_write_fd = -1;
-+
-+static int method_something(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
-+        _cleanup_(json_variant_unrefp) JsonVariant *ret = NULL;
-+        JsonVariant *a, *b;
-+        intmax_t x, y;
-+        int r;
-+
-+        a = json_variant_by_key(parameters, "a");
-+        if (!a)
-+                return varlink_error(link, "io.test.BadParameters", NULL);
-+
-+        x = json_variant_integer(a);
-+
-+        b = json_variant_by_key(parameters, "b");
-+        if (!b)
-+                return varlink_error(link, "io.test.BadParameters", NULL);
-+
-+        y = json_variant_integer(b);
-+
-+        r = json_build(&ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("sum", JSON_BUILD_INTEGER(x + y))));
-+        if (r < 0)
-+                return r;
-+
-+        return varlink_reply(link, ret);
-+}
-+
-+static int method_done(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
-+
-+        if (++n_done == 2)
-+                sd_event_exit(varlink_get_event(link), EXIT_FAILURE);
-+
-+        return 0;
-+}
-+
-+static int reply(Varlink *link, JsonVariant *parameters, const char *error_id, VarlinkReplyFlags flags, void *userdata) {
-+        JsonVariant *sum;
-+
-+        sum = json_variant_by_key(parameters, "sum");
-+
-+        assert_se(json_variant_integer(sum) == 7+22);
-+
-+        if (++n_done == 2)
-+                sd_event_exit(varlink_get_event(link), EXIT_FAILURE);
-+
-+        return 0;
-+}
-+
-+static int on_connect(VarlinkServer *s, Varlink *link, void *userdata) {
-+        uid_t uid = UID_INVALID;
-+
-+        assert(s);
-+        assert(link);
-+
-+        assert_se(varlink_get_peer_uid(link, &uid) >= 0);
-+        assert_se(getuid() == uid);
-+
-+        return 0;
-+}
-+
-+static int overload_reply(Varlink *link, JsonVariant *parameters, const char *error_id, VarlinkReplyFlags flags, void *userdata) {
-+
-+        /* This method call reply should always be called with a disconnection, since the method call should
-+         * be talking to an overloaded server */
-+
-+        log_debug("Over reply triggered with error: %s", strna(error_id));
-+        assert_se(streq(error_id, VARLINK_ERROR_DISCONNECTED));
-+        sd_event_exit(varlink_get_event(link), 0);
-+
-+        return 0;
-+}
-+
-+static void flood_test(const char *address) {
-+        _cleanup_(varlink_flush_close_unrefp) Varlink *c = NULL;
-+        _cleanup_(sd_event_unrefp) sd_event *e = NULL;
-+        _cleanup_free_ Varlink **connections = NULL;
-+        size_t k;
-+        char x = 'x';
-+
-+        log_debug("Flooding server...");
-+
-+        /* Block the main event loop while we flood */
-+        assert_se(write(block_write_fd, &x, sizeof(x)) == sizeof(x));
-+
-+        assert_se(sd_event_default(&e) >= 0);
-+
-+        /* Flood the server with connections */
-+        assert_se(connections = new0(Varlink*, OVERLOAD_CONNECTIONS));
-+        for (k = 0; k < OVERLOAD_CONNECTIONS; k++) {
-+                _cleanup_free_ char *t = NULL;
-+                log_debug("connection %zu", k);
-+                assert_se(varlink_connect_address(connections + k, address) >= 0);
-+
-+                assert_se(asprintf(&t, "flood-%zu", k) >= 0);
-+                assert_se(varlink_set_description(connections[k], t) >= 0);
-+                assert_se(varlink_attach_event(connections[k], e, k) >= 0);
-+                assert_se(varlink_sendb(connections[k], "io.test.Rubbish", JSON_BUILD_OBJECT(JSON_BUILD_PAIR("id", JSON_BUILD_INTEGER(k)))) >= 0);
-+        }
-+
-+        /* Then, create one more, which should fail */
-+        log_debug("Creating overload connection...");
-+        assert_se(varlink_connect_address(&c, address) >= 0);
-+        assert_se(varlink_set_description(c, "overload-client") >= 0);
-+        assert_se(varlink_attach_event(c, e, k) >= 0);
-+        assert_se(varlink_bind_reply(c, overload_reply) >= 0);
-+        assert_se(varlink_invokeb(c, "io.test.Overload", JSON_BUILD_OBJECT(JSON_BUILD_PAIR("foo", JSON_BUILD_STRING("bar")))) >= 0);
-+
-+        /* Unblock it */
-+        log_debug("Unblocking server...");
-+        block_write_fd = safe_close(block_write_fd);
-+
-+        /* This loop will terminate as soon as the overload reply callback is called */
-+        assert_se(sd_event_loop(e) >= 0);
-+
-+        /* And close all connections again */
-+        for (k = 0; k < OVERLOAD_CONNECTIONS; k++)
-+                connections[k] = varlink_unref(connections[k]);
-+}
-+
-+static void *thread(void *arg) {
-+        _cleanup_(varlink_flush_close_unrefp) Varlink *c = NULL;
-+        _cleanup_(json_variant_unrefp) JsonVariant *i = NULL;
-+        JsonVariant *o = NULL;
-+        const char *e;
-+
-+        assert_se(json_build(&i, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("a", JSON_BUILD_INTEGER(88)),
-+                                                   JSON_BUILD_PAIR("b", JSON_BUILD_INTEGER(99)))) >= 0);
-+
-+        assert_se(varlink_connect_address(&c, arg) >= 0);
-+        assert_se(varlink_set_description(c, "thread-client") >= 0);
-+
-+        assert_se(varlink_call(c, "io.test.DoSomething", i, &o, &e, NULL) >= 0);
-+        assert_se(json_variant_integer(json_variant_by_key(o, "sum")) == 88 + 99);
-+        assert_se(!e);
-+
-+        assert_se(varlink_callb(c, "io.test.IDontExist", &o, &e, NULL, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("x", JSON_BUILD_REAL(5.5)))) >= 0);
-+        assert_se(streq_ptr(json_variant_string(json_variant_by_key(o, "method")), "io.test.IDontExist"));
-+        assert_se(streq(e, VARLINK_ERROR_METHOD_NOT_FOUND));
-+
-+        flood_test(arg);
-+
-+        assert_se(varlink_send(c, "io.test.Done", NULL) >= 0);
-+
-+        return NULL;
-+}
-+
-+static int block_fd_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
-+        char c;
-+
-+        assert_se(fd_nonblock(fd, false) >= 0);
-+
-+        assert_se(read(fd, &c, sizeof(c)) == sizeof(c));
-+        /* When a character is written to this pipe we'll block until the pipe is closed. */
-+
-+        assert_se(read(fd, &c, sizeof(c)) == 0);
-+
-+        assert_se(fd_nonblock(fd, true) >= 0);
-+
-+        assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
-+
-+        return 0;
-+}
-+
-+int main(int argc, char *argv[]) {
-+        _cleanup_(sd_event_source_unrefp) sd_event_source *block_event = NULL;
-+        _cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL;
-+        _cleanup_(varlink_flush_close_unrefp) Varlink *c = NULL;
-+        _cleanup_(rm_rf_physical_and_freep) char *tmpdir = NULL;
-+        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
-+        _cleanup_(sd_event_unrefp) sd_event *e = NULL;
-+        _cleanup_(close_pairp) int block_fds[2] = { -1, -1 };
-+        pthread_t t;
-+        const char *sp;
-+
-+        log_set_max_level(LOG_DEBUG);
-+        log_open();
-+
-+        assert_se(mkdtemp_malloc("/tmp/varlink-test-XXXXXX", &tmpdir) >= 0);
-+        sp = strjoina(tmpdir, "/socket");
-+
-+        assert_se(sd_event_default(&e) >= 0);
-+
-+        assert_se(pipe2(block_fds, O_NONBLOCK|O_CLOEXEC) >= 0);
-+        assert_se(sd_event_add_io(e, &block_event, block_fds[0], EPOLLIN, block_fd_handler, NULL) >= 0);
-+        assert_se(sd_event_source_set_priority(block_event, SD_EVENT_PRIORITY_IMPORTANT) >= 0);
-+        block_write_fd = TAKE_FD(block_fds[1]);
-+
-+        assert_se(varlink_server_new(&s, VARLINK_SERVER_ACCOUNT_UID) >= 0);
-+        assert_se(varlink_server_set_description(s, "our-server") >= 0);
-+
-+        assert_se(varlink_server_bind_method(s, "io.test.DoSomething", method_something) >= 0);
-+        assert_se(varlink_server_bind_method(s, "io.test.Done", method_done) >= 0);
-+        assert_se(varlink_server_bind_connect(s, on_connect) >= 0);
-+        assert_se(varlink_server_listen_address(s, sp, 0600) >= 0);
-+        assert_se(varlink_server_attach_event(s, e, 0) >= 0);
-+        assert_se(varlink_server_set_connections_max(s, OVERLOAD_CONNECTIONS) >= 0);
-+
-+        assert_se(varlink_connect_address(&c, sp) >= 0);
-+        assert_se(varlink_set_description(c, "main-client") >= 0);
-+        assert_se(varlink_bind_reply(c, reply) >= 0);
-+
-+        assert_se(json_build(&v, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("a", JSON_BUILD_INTEGER(7)),
-+                                                   JSON_BUILD_PAIR("b", JSON_BUILD_INTEGER(22)))) >= 0);
-+
-+        assert_se(varlink_invoke(c, "io.test.DoSomething", v) >= 0);
-+
-+        assert_se(varlink_attach_event(c, e, 0) >= 0);
-+
-+        assert_se(pthread_create(&t, NULL, thread, (void*) sp) == 0);
-+
-+        assert_se(sd_event_loop(e) >= 0);
-+
-+        assert_se(pthread_join(t, NULL) == 0);
-+
-+        return 0;
-+}
diff --git a/debian/patches/apertis/units-automatically-revert-to-run-logging-on-shutdown-if-.patch b/debian/patches/apertis/units-automatically-revert-to-run-logging-on-shutdown-if-.patch
deleted file mode 100644
index c8fa3d00f551fc7e7424200bd169fb902cdd3400..0000000000000000000000000000000000000000
--- a/debian/patches/apertis/units-automatically-revert-to-run-logging-on-shutdown-if-.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From: Lennart Poettering <lennart@poettering.net>
-Date: Fri, 5 Apr 2019 18:22:31 +0200
-Subject: units: automatically revert to /run logging on shutdown if necessary
-
-Fixes: #867
-
-Signed-off-by: Martyn Welch <martyn.welch@collabora.com>
-[Martyn Welch: Backported to systemd v241]
----
- units/systemd-journal-flush.service.in | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/units/systemd-journal-flush.service.in b/units/systemd-journal-flush.service.in
-index bacfe51..29b006c 100644
---- a/units/systemd-journal-flush.service.in
-+++ b/units/systemd-journal-flush.service.in
-@@ -18,6 +18,7 @@ RequiresMountsFor=/var/log/journal
- 
- [Service]
- ExecStart=@rootbindir@/journalctl --flush
-+ExecStop=@rootbindir@/journalctl --smart-relinquish-var
- Type=oneshot
- RemainAfterExit=yes
- TimeoutSec=90s
diff --git a/debian/patches/disable-failing-tests.patch b/debian/patches/disable-failing-tests.patch
deleted file mode 100644
index 552f67aa19e01b13301e8cd52d50db097621cee5..0000000000000000000000000000000000000000
--- a/debian/patches/disable-failing-tests.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-Disable tests: test-stat-util, test-netlink
-These tests are reported to fail in Bosch's build setup
---- a/src/test/meson.build
-+++ b/src/test/meson.build
-@@ -280,10 +280,6 @@
-          [],
-          []],
- 
--        [['src/test/test-stat-util.c'],
--         [],
--         []],
--
-         [['src/test/test-os-util.c'],
-          [],
-          []],
-@@ -919,10 +915,6 @@
-          [],
-          []],
- 
--        [['src/libsystemd/sd-netlink/test-netlink.c'],
--         [],
--         []],
--
-         [['src/libsystemd/sd-netlink/test-local-addresses.c'],
-          [],
-          []],
diff --git a/debian/patches/sd-boot-fix-menu-ordering-with-boot-counting.patch b/debian/patches/sd-boot-fix-menu-ordering-with-boot-counting.patch
deleted file mode 100644
index d9cf2d9c9531219a3d366c6bb2ae8679f1cf3ef8..0000000000000000000000000000000000000000
--- a/debian/patches/sd-boot-fix-menu-ordering-with-boot-counting.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From e6190e2882e1d6772a9e586fcc65c91d406e52fb Mon Sep 17 00:00:00 2001
-From: Daniel Fullmer <danielrf12@gmail.com>
-Date: Thu, 23 Apr 2020 14:47:56 -0400
-Subject: sd-boot: fix menu ordering with boot counting
-
-systemd-boot selects the last valid entry by default, not the first.
-
-Fixes: #15256
-
-diff --git a/docs/AUTOMATIC_BOOT_ASSESSMENT.md b/docs/AUTOMATIC_BOOT_ASSESSMENT.md
-index aff203b590..83ddf28fdd 100644
---- a/docs/AUTOMATIC_BOOT_ASSESSMENT.md
-+++ b/docs/AUTOMATIC_BOOT_ASSESSMENT.md
-@@ -99,9 +99,9 @@ Here's an example walkthrough of how this all fits together.
-
- 6. If this boot also fails, on the next boot the boot loader will see the the
-    tag `+0-3`, i.e. the counter reached zero. At this point the entry will be
--   considered "bad", and ordered to the end of the list of entries. The next
--   newest boot entry is now tried, i.e. the system automatically reverted back
--   to an earlier version.
-+   considered "bad", and ordered to the beginning of the list of entries. The
-+   next newest boot entry is now tried, i.e. the system automatically reverted
-+   back to an earlier version.
-
- The above describes the walkthrough when the selected boot entry continuously
- fails. Let's have a look at an alternative ending to this walkthrough. In this
-diff --git a/man/systemd-boot.xml b/man/systemd-boot.xml
-index dacd49cd7b..b666ae1e53 100644
---- a/man/systemd-boot.xml
-+++ b/man/systemd-boot.xml
-@@ -391,10 +391,10 @@
-     considered 'good' from then on.</para>
-
-     <para>The boot menu takes the 'tries left' counter into account when sorting the menu entries: entries in 'bad'
--    state are ordered at the end of the list, and entries in 'good' or 'indeterminate' at the beginning. The user can
-+    state are ordered at the beginning of the list, and entries in 'good' or 'indeterminate' at the end. The user can
-     freely choose to boot any entry of the menu, including those already marked 'bad'. If the menu entry to boot is
--    automatically determined, this means that 'good' or 'indeterminate' entries are generally preferred (as the top item of
--    the menu is the one booted by default), and 'bad' entries will only be considered if there are no 'good' or
-+    automatically determined, this means that 'good' or 'indeterminate' entries are generally preferred (as the bottom
-+    item of the menu is the one booted by default), and 'bad' entries will only be considered if there are no 'good' or
-     'indeterminate' entries left.</para>
-
-     <para>The <citerefentry><refentrytitle>kernel-install</refentrytitle><manvolnum>8</manvolnum></citerefentry> kernel
-diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
-index 380b530fd2..1fe2a2bdc3 100644
---- a/src/boot/efi/boot.c
-+++ b/src/boot/efi/boot.c
-@@ -1479,11 +1479,11 @@ static VOID config_load_entries(
- static INTN config_entry_compare(ConfigEntry *a, ConfigEntry *b) {
-         INTN r;
-
--        /* Order entries that have no tries left to the end of the list */
-+        /* Order entries that have no tries left to the beginning of the list */
-         if (a->tries_left != 0 && b->tries_left == 0)
--                return -1;
--        if (a->tries_left == 0 && b->tries_left != 0)
-                 return 1;
-+        if (a->tries_left == 0 && b->tries_left != 0)
-+                return -1;
-
-         r = str_verscmp(a->id, b->id);
-         if (r != 0)
-@@ -1493,17 +1493,17 @@ static INTN config_entry_compare(ConfigEntry *a, ConfigEntry *b) {
-             b->tries_left == (UINTN) -1)
-                 return 0;
-
--        /* If both items have boot counting, and otherwise are identical, put the entry with more tries left first */
-+        /* If both items have boot counting, and otherwise are identical, put the entry with more tries left last */
-         if (a->tries_left > b->tries_left)
--                return -1;
--        if (a->tries_left < b->tries_left)
-                 return 1;
-+        if (a->tries_left < b->tries_left)
-+                return -1;
-
-         /* If they have the same number of tries left, then let the one win which was tried fewer times so far */
-         if (a->tries_done < b->tries_done)
--                return -1;
--        if (a->tries_done > b->tries_done)
-                 return 1;
-+        if (a->tries_done > b->tries_done)
-+                return -1;
-
-         return 0;
- }
diff --git a/debian/patches/series b/debian/patches/series
index 4a62df46d442c0e059b32111ed6e260e246a4158..b13e7a69b63f5b30a033e6f8583d5cf5765328c7 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -21,19 +21,7 @@ debian/Keep-journal-files-compatible-with-older-versions.patch
 debian/Move-sysusers.d-sysctl.d-binfmt.d-modules-load.d-back-to-.patch
 debian/systemctl-do-not-shutdown-immediately-on-scheduled-shutdo.patch
 debian/test-disable-DnsmasqClientTest.test_resolved_etc_hosts-in.patch
-
-apertis/0001-Remove-bashisms-from-the-depmod-wrapper.patch
-apertis/0002-Remove-bashisms-from-the-UEFI-entries-generator.patch
-apertis/0003-Reworked-kernel-install-script.patch
-disable-failing-tests.patch
-apertis/shared-add-minimal-varlink-implementation.patch
-apertis/tests-add-varlink-test.patch
-apertis/fuzzer-add-varlink-fuzzer.patch
-apertis/journald-also-offer-flush-rotate-sync-as-varlink-method-c.patch
-apertis/journalctl-port-flush-sync-rotate-to-use-varlink-method-c.patch
-apertis/journald-add-API-to-move-logging-from-var-to-run-again.patch
-apertis/journalctl-add-new-relinquish-and-smart-relinquish-option.patch
-apertis/units-automatically-revert-to-run-logging-on-shutdown-if-.patch
-sd-boot-fix-menu-ordering-with-boot-counting.patch
-apertis/Force-the-call-of-systemd-journal-flush-before-var-u.patch
 apertis/Add-usr-to-non-unmountable-list.patch
+apertis/Remove-bashisms-from-the-depmod-wrapper.patch
+apertis/Remove-bashisms-from-the-UEFI-entries-generator.patch
+apertis/Reworked-kernel-install-script.patch