У меня произошел сбой при запуске . В моем случае сбой произошел после достижения цели basic.target
, но до multi-user.target
, поэтому я хотел выяснить, какая из служб, запущенных с помощью multi-user.target
, вызвала сбой.
Сначала я организовал загрузку с basic.target
плюс корневой шелл. Вы можете сделать это навсегда (при условии, что вам вообще удастся загрузиться! )с
systemctl set-default basic.target
systemctl enable debug-shell
Служба debug-shell
запускает корневую оболочку на tty 9.
Тот же эффект можно получить, добавив параметры systemd.unit=basic.target systemd.debug-shell
в командную строку ядра. Например, в Grub измените командную строку на что-то вроде
linux /vmlinuz-4.13.0-38-generic root=/dev/mapper/crypt-root ro systemd.unit=basic.target systemd.debug-shell
В этой оболочке я запустил следующий сценарий, чтобы запускать службы одну за другой. Обратите внимание, что это практически не тестировалось. (Я запускал его один раз, и он, как и ожидалось, аварийно завершил работу с проблемной службой ).
#!/bin/sh
wants=$(systemctl show -p Wants multi-user.target | sed 's/^Wants=//' | tr ' ' '\n' | sort)
log=/var/tmp/multi-user-steps-$(date +%Y%m%d-%H%M%S)
log () {
echo "$*..." | tee -a "$log"
sync
"$@"
ret=$?
echo "$* -> $ret" | tee -a "$log"
sync
return $ret
}
# systemd services
for service in $wants; do
log systemctl start $service
sleep 2
done
# upstart services
for conf in /etc/init/*.conf; do
service=${conf##*/}; service=${service%.conf}
log service ${service} start
sleep 2
done
# sysvinit services
for service in /etc/rc3.d/S*; do
log ${service} start
sleep 2
done
В приведенном ниже сценарии объявляются зависимости «До» для модулей systemd, которые являются прямыми зависимостями данной цели, чтобы заставить их выполняться в определенном порядке. Вы можете запустить его на multi-user.target
или basic.target
.
Обратите внимание, что этот скрипт не работает в целом потому что он не принимает во внимание существующие зависимости :он может вызвать зацикливание зависимостей. Правильный скрипт должен собирать существующие зависимости и производить топологическую сортировку. Я решил свою проблему, поэтому больше не собираюсь над ней работать; Я публикую его на случай, если кто-то захочет адаптировать его к своим потребностям.
Также обратите внимание, что это не влияет на службы Upstart и SysVinit.
Перед запуском сделайте резервную копию /etc
! (Я настоятельно рекомендую использовать etckeeper .)
#!/bin/sh
set -e
if [ $# -eq 0 ] || [ "$1" = "--help" ]; then
cat <"$service_dir/$want.d/linearize-for-${target%.*}.conf"
[Unit]
Before=$previous
EOF
previous=$want
done
#!/bin/ksh
JENKINS_URL=$1
# extract just the host and potental port number from the url
HOSTP=${JENKINS_URL#*:} ; HOSTP=${HOSTP%%/*}
# Create down directory if it doesn't exist
[ -d down ] || mkdir -p down
curl --connect-timeout 10 "$JENKINS_URL" >/dev/null
status=$?
if [ "$status" == "7" ]; then
[ -e "down/$HOSTP" ] && exit 0
{ echo -n "$HOSTP down " ; date } >> times
touch "down/$HOSTP"
SUBJECT="Connection refused or can not connect to URL $JENKINS_URL"
echo "$SUBJECT"|/usr/sbin/sendmail -t XXXX@gmail.com
else
echo "successfully connected $JENKINS_URL"
[ -e "down/$HOSTP" ] || exit 0
rm "down/$HOSTP"
{ echo -n "$HOSTP up " ; date } >> times
fi
exit 0