#!/bin/sh -e

. /usr/lib/s6-policy-common/lib/svctl-common.sh

policy=$(readlink /usr/lib/s6-rc/policy/current)
if test x"$policy" = x"exclusive" ; then
  top="top"
elif test x"$policy" = x"shared" ; then
  top="runlevel_2"
else
  echo "svctl-apply: fatal: /usr/lib/s6-rc/policy/current should be a relative symlink to either shared or exclusive" 1>&2
  exit 100
fi

/usr/lib/s6-policy-common/bin/svctl-update

# WITH a time limit -- without one s6-rc waits forever, and this is the most
# expensive path of all: "invoke-rc.d <service> start" ends up in exactly this
# apply, and foreign postinsts call it on every installation. Measured on
# 24.09.2026 with zabbix-proxy: "s6-rc -p change top" ran for 150 seconds and
# counting while dpkg held its lock -- although 1.1.2 had lowered the limit for
# dpkg runs to 20 s. The reason was this line: 1.0.7 added the limit to
# svctl-update/start/stop/restart and forgot apply. The number was right and
# had no effect.
timeout="$(svctl_timeout)"
rc=0
s6-rc -p -t "$timeout" change "$top" || rc=$?
if [ "$rc" != 0 ]; then
  echo "svctl-apply: fatal: the transition to '$top' failed or exceeded the limit of" 1>&2
  echo "svctl-apply:        ${timeout} ms (s6-rc rc=${rc})." 1>&2
  # No detailed diagnosis here: "svctl liststate" says which services hang more
  # honestly than a list guessed from the state BEFORE the transition. If the
  # lock is held, that is an answer too.
  if ! svctl_load_active; then
    svctl_report_unmeasurable
  else
    echo "svctl-apply:        'svctl liststate' shows which services are not in the wanted state." 1>&2
  fi
  exit "$rc"
fi
