SystemD 해킹하기
저는 10년 넘게 임베디드 리눅스 시스템을 구축해 왔으며, sysV 스타일 init을 광범위하게 다뤄왔습니다. 이는 견고하고 오랜 시간 검증된 방식이지만, 한계도 있습니다. 현재 Upstart와 systemd 같은 여러 프로젝트가 sysvinit을 대체하는 것을 목표로 하고 있습니다.
저는 Fedora를 광범위하게 사용하며, 디스크 없는 워크스테이션용 nfsroot 파일시스템과 Fedora 저장소를 기반으로 한 임베디드 펌웨어를 모두 구축합니다. 이러한 작업에 Fedora는 다소 특이한 선택입니다. 대부분의 사람들은 Debian이나 Ubuntu를 선택할 테니까요.
Fedora는 릴리스 15에서 systemd로 전환했습니다. systemd가 새로웠기 때문에, 저는 툴체인을 Fedora 15로 업그레이드하지 않기로 했습니다. 이제 17에 와 있고, systemd는 안정적으로 보입니다. 그래서 Fedora 17을 사용하여 nfsroot 시스템을 구축했습니다. 결과는 LTSP5/Meukow와 유사하지만, Fedora가 최신 릴리스를 제공하므로 모든 패키지가 훨씬 최신입니다.
systemd에 관한 문서는 부족하며, systemd를 축소하는 방법을 알아내는 데 몇 가지 어려움을 겪었습니다. sysvinit을 사용하면 축소가 더 쉽습니다. rc.sysinit을 간소해질 때까지 편집하고, chkconfig를 사용하여 관련 없는 서비스를 끄고, SELinux를 비활성화하면 됩니다. Fedora 팀은 systemd의 조정과 사용에 관한 몇 가지 유용한 문서를 올려두었습니다. 또한 sysVinit에서 systemd로의 치트시트와 디버깅 가이드도 있습니다. 이 페이지들이 제게 큰 도움이 되었습니다.
제 nfsroot 파일시스템은 첫 번째 시도에서 부팅에 실패했습니다.
systemd.confirm_spawn=true
를 커널 명령줄에 추가함으로써 systemd가 실행하는 각 명령을 확인하고 어느 것이 충돌하는지 알아낼 수 있었습니다.
systemd의 유용한 기능 중 하나는 chroot 파일시스템에 chroot하지 않고도 chkconfig 스타일 명령을 실행할 수 있다는 것입니다. 이는 파일시스템을 처음 구축할 때 사용했던 yum의 --installroot 옵션과 유사합니다. 예를 들어, 방금 구축한 시스템에서 cron을 비활성화하려면 다음을 실행하세요.
systemctl --system --root=$TARGET disable crond.service
여기서 $TARGET은 chroot의 경로입니다.
Systemd는 위 명령으로 비활성화할 수 없는 여러 서비스를 실행합니다. 이러한 서비스/명령에 대한 심볼릭 링크는 /etc/systemd에도 존재하지 않습니다. 제가 찾은 유일한 방법은 /lib/systemd/system에서 이러한 명령에 대한 심볼릭 링크를 삭제하는 것이었습니다. 임베디드/데스크톱 시스템에서 불필요하다고 판단한 명령 중 일부는 다음과 같습니다.
/lib/systemd/system/sysinit.target.wants/*binfmt*
/lib/systemd/system/sysinit.target.wants/cryptsetup.target
/lib/systemd/system/sysinit.target.wants/dev-hugepages.target
/lib/systemd/system/basic.target.wants/fedora-configure.service
/lib/systemd/system/local-fs.target.wants/fedora-import-state.service
/lib/systemd/system/local-fs.target.wants/fedora-readonly.service
/lib/systemd/system/local-fs.target.wants/fedora-storage-init*.service