#!/bin/sh -e

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

if test -z "$1" ; then
  echo "svctl-restart: usage: svctl-restart service..." 1>&2
  exit 100
fi

if ! test -L /run/s6-rc/compiled ; then
  echo "svctl-restart: fatal: s6-rc is not running" 1>&2
  exit 2
fi

list=$(s6-rc-db atomics "$@")

# Oneshots have to be taken down before they can run again: "s6-rc -u change" on
# an already-active oneshot is a no-op, so until 2026-09-22 "svctl restart" on a
# oneshot did nothing at all and still exited 0 -- every "notify => Service[...]"
# on a oneshot was silently lost (S6-SYSTEM.md, and the Puppet provider reported
# "Triggered 'refresh'" for it).
#
# Note what this implies: taking a oneshot down takes its dependants down too,
# and "s6-rc -u change" below brings the named service back up, not them. That is
# s6-rc's dependency semantics, and it is the reason this only happens for
# oneshots that are actually up -- restarting a stopped one would have no
# meaning either way.
downagain=""
for i in $list ; do
  t=$(s6-rc-db type "$i")
  if test x"$t" = x"longrun" ; then
    s6-svc -r "/run/s6-rc/scandir/$i"
  elif test x"$t" = x"oneshot" ; then
    if s6-rc -a list | grep -qFx "$i" ; then
      downagain="$downagain $i"
    fi
  fi
done

timeout="$(svctl_timeout)"

if test -n "$downagain" ; then
  # shellcheck disable=SC2086
  rc=0
  s6-rc -t "$timeout" -d change $downagain || rc=$?
  if [ "$rc" -ne 0 ]; then
    echo "svctl-restart: fatal: das Herunterfahren der Oneshots ist fehlgeschlagen oder hat" 1>&2
    echo "svctl-restart:        das Limit von ${timeout} ms gerissen (s6-rc rc=${rc})." 1>&2
    # shellcheck disable=SC2086
    svctl_report_pending down $downagain
    exit "$rc"
  fi
fi

# Mit Zeitlimit: ein Dienst, der beim Neustart haengt, darf kein postinst und
# keinen Puppet-Lauf blockieren (siehe svctl-update.unlocked).
rc=0
s6-rc -t "$timeout" -u change "$@" || rc=$?
if [ "$rc" -ne 0 ]; then
  echo "svctl-restart: fatal: der Zustandswechsel ist fehlgeschlagen oder hat das Limit von" 1>&2
  echo "svctl-restart:        ${timeout} ms gerissen (s6-rc rc=${rc})." 1>&2
  svctl_report_pending up "$@"
  exit "$rc"
fi
