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
달리기 전에 백업하세요! (저는 다음을 사용하는 것을 적극 권장합니다.관리자를 기다려주세요.)
#!/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