
Ubuntu 17.04에서 부팅이 실패하여 디버깅하고 싶습니다.
부팅이 무작위로 실패하고 경쟁 조건으로 인한 것이라고 생각합니다.
어떤 작업도 병렬화하지 않도록 요청하여 systemd
예상대로 부팅이 실패하는지 확인할 수 있습니까?
답변1
해결 방법: 서비스를 수동으로 실행
나는 가지고 있었다시작 중 충돌. 내 경우에는 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
추가 종속성 추가
아래 스크립트는 특정 대상이 특정 순서로 실행되도록 강제하기 위해 특정 대상의 직접적인 종속성인 시스템 단위에 대한 "이전" 종속성을 선언합니다. multi-user.target
또는 에서 실행할 수도 있습니다 basic.target
.
참고하세요이 스크립트는 일반적으로 작동하지 않습니다기존 종속성을 고려하지 않기 때문에 종속성 루프가 발생할 수 있습니다. 적절한 스크립트는 기존 종속성을 수집하고 토폴로지 정렬을 수행해야 합니다. 문제를 해결했으므로 더 이상 작업할 생각이 없습니다. 누군가 자신의 필요에 맞게 조정하고 싶을 경우를 대비하여 게시하고 있습니다.
이는 Upstart 및 SysVinit 서비스에는 영향을 미치지 않습니다.
/etc
실행하기 전에 백업해두세요 ! (사용을 강력히 권장합니다.etckeeper.)
#!/bin/sh
set -e
if [ $# -eq 0 ] || [ "$1" = "--help" ]; then
cat <<EOF
Usage: $0 TARGET
Linearize the dependencies of a systemd target so it starts deterministically.
This scripts adds systemd unit files called linearize-for*.conf containing
extra Before= dependencies for each dependency of TARGET.
EOF
fi
service_dir=/etc/systemd/system
target=$1
wants=$(systemctl show -p Wants "$target" | sed 's/[^= ]*=//' |
tr ' ' '\n' | sort)
previous=
for want in $wants; do
[ -d "$service_dir/$want.d" ] || mkdir "$service_dir/$want.d"
cat <<EOF >"$service_dir/$want.d/linearize-for-${target%.*}.conf"
[Unit]
Before=$previous
EOF
previous=$want
done