읽기 전용/파일 시스템에서 systemd-timesync 사용

읽기 전용/파일 시스템에서 systemd-timesync 사용

읽기 전용 파일 시스템으로 Raspberry Pi를 설정하려고 합니다. 기본 이미지는 Debian Buster lite Raspbian 이미지입니다.
다음과 같은 간단한 수정이 필요한 경우 대부분의 작업이 작동합니다.

mv /etc/resolv.conf /var/run/resolv.conf && ln -s /var/run/resolv.conf /etc/resolv.conf

DHCP 및 기타 서비스와 유사

그러나 서비스를 원하지만 systemd-timesync와 같은 작동을 거부합니다.

내가 한 일과 일어난 일은 다음과 같습니다. systemd-timesync 사용자 systemd-timesync:systemd-timesync가 소유한 /run/systemd-timesync 디렉토리를 만든 다음 /var/lib/systemd/timesync -> /run/systemd -timesync 심볼릭 링크를 만들었습니다.

root@raspberrypi:/var/lib/systemd # ls -l /var/lib/systemd/timesync
lrwxrwxrwx 1 root root 21 Dec 25 14:48 /var/lib/systemd/timesync -> /run/systemd-timesync

root@raspberrypi:/var/lib/systemd # ls -l /run/systemd-timesync/
total 0
-rw-r--r-- 1 systemd-timesync systemd-timesync 0 Dec 25 15:02 clock

시스템 단위 파일의 관련 부분:

...
[Service]
User=systemd-timesync
AmbientCapabilities=CAP_SYS_TIME
CapabilityBoundingSet=CAP_SYS_TIME
WorkingDirectory=/run/systemd-timesync
Environment=SYSTEMD_LOG_LEVEL=debug
ExecStartPre=/bin/pwd
ExecStart=!!/lib/systemd/systemd-timesyncd
...
RuntimeDirectory=systemd/timesync
StateDirectory=systemd/timesync
...

현재 작업 디렉터리만 로그에 출력하는 ExecStartPre=/bin/pwd를 추가했습니다.

이제 systemd-timesync를 시작하고 /를 읽기 전용으로 마운트하면 다음과 같은 일이 발생합니다.

root@raspberrypi:/var/lib/systemd # systemctl stop systemd-timesyncd.service && systemctl daemon-reload && systemctl start systemd-timesyncd.service
Job for systemd-timesyncd.service failed because of unavailable resources or another system error.
See "systemctl status systemd-timesyncd.service" and "journalctl -xe" for details.

Journalctl 출력

Dec 25 15:34:10 raspberrypi systemd[1]: systemd-timesyncd.service: Trying to enqueue job systemd-timesyncd.service/stop/replace
Dec 25 15:34:10 raspberrypi systemd[1]: systemd-timesyncd.service: Installed new job systemd-timesyncd.service/stop as 1214
Dec 25 15:34:10 raspberrypi systemd[1]: systemd-timesyncd.service: Enqueued job systemd-timesyncd.service/stop as 1214
Dec 25 15:34:10 raspberrypi systemd[1]: systemd-timesyncd.service: Job 1214 systemd-timesyncd.service/stop finished, result=done
Dec 25 15:34:10 raspberrypi systemd[1]: /lib/systemd/system/systemd-timesyncd.service:36: Failed to parse system call, ignoring: io_pgetevents
Dec 25 15:34:10 raspberrypi systemd[1]: systemd-timesyncd.service: Changed dead -> failed
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: Trying to enqueue job systemd-timesyncd.service/start/replace
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: Installed new job systemd-timesyncd.service/start as 1215
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: Enqueued job systemd-timesyncd.service/start as 1215
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: ConditionFileIsExecutable=!/usr/sbin/VBoxService succeeded.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: ConditionFileIsExecutable=!/usr/sbin/chronyd succeeded.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: ConditionFileIsExecutable=!/usr/sbin/openntpd succeeded.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: ConditionFileIsExecutable=!/usr/sbin/ntpd succeeded.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: ConditionVirtualization=!container succeeded.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: ConditionCapability=CAP_SYS_TIME succeeded.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: Failed to run 'start-pre' task: Read-only file system
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: Failed with result 'resources'.
Dec 25 15:34:11 raspberrypi systemd[1]: systemd-timesyncd.service: Job 1215 systemd-timesyncd.service/start finished, result=failed
Dec 25 15:34:11 raspberrypi systemd[1]: Failed to start Network Time Synchronization.

분명히 읽기 전용 파일 시스템으로 인해 ExecStartPre의 /bin/pwd가 실패했습니다. 나는 이것을 이해하지 못하고 그것을 고치는 방법을 모릅니다. ExecStartPre를 제거하면 ExecStart 명령에서도 같은 일이 발생합니다.

그러나 내가 이것을 할 때,

mount -o remount,rw /

그후

root@raspberrypi:/var/lib/systemd # systemctl stop systemd-timesyncd.service && systemctl daemon-reload && systemctl start systemd-timesyncd.service

로그에 대한 pwd 출력을 포함하여 모든 것이 잘 작동합니다.

마찬가지로 시작할 때도

root@raspberrypi:/var/lib/systemd # /lib/systemd/systemd-timesyncd
Synchronized to time server for the first time 84.199.86.247:123 (0.debian.pool.ntp.org).

모든 것이 정상입니다.

지금까지 내 결론은 systemd가 ExecStartPre 또는 ExecStart에서 명령을 시작하려면 어딘가에 쓰기 액세스 권한이 필요하다는 것입니다.

Raspberry가 시간 설정을 업데이트하도록 하는 원래 목표를 달성하는 방법에 대한 아이디어가 있습니까?

참고: 이는 유닛 파일의 StateDirectory 및 RuntimeDirectory 행과 관련이 있을 수 있습니다.

답변1

이것은 DietPi의 문제를 해결했습니다.

  • /run은 tmpfs로 마운트됩니다.

  • /var/lib 아래에 StateDirectory에 대한 소프트 링크를 만듭니다.

    ln -s /run /var/lib/run

  • 비활성화PrivateTmp

    #PrivateTmp=yes

  • StateDirectory를 tmpfs로 변경합니다.

    StateDirectory=run/timesync

RuntimeDirectory는 /run에 대해 절대적이며 이미 tmpfs이므로 변경할 필요가 없습니다.

답변2

오랜 수정 끝에 [Unit] 섹션에서 다음 두 줄을 주석 처리하는 것만으로도 충분하다는 것이 밝혀졌습니다.

#CapabilityBoundingSet=CAP_SYS_TIME
#PrivateTmp=yes

읽기 전용/파일 시스템에서 제대로 작동하려면 주석 처리가 필요한 유일한 두 줄이 있는 것으로 나타났습니다.

이 줄 중 하나의 주석 처리를 제거하면 읽기 전용 파일 시스템에서 systemd-timesync의 작동이 중단되는 이유를 이해할 수 없습니다. 나는 PrivateTmp=yes가 프로세스에 대해 private /tmp에 마운트된 개인 tmpfs를 생성할 것으로 예상했지만 분명히 그렇지 않습니다. 그렇다면 systemd의 버그일 수도 있습니다.

답변3

overlayfs읽기 전용(그러나 가짜 쓰기 가능)/파일 시스템 사용을 고려해야 합니다 . 이렇게 하면 특정 시스템 서비스가 실패하는 것을 방지할 수 있습니다.

raspi-config> 의 스크립트를 사용하여 이 작업을 수행 할 수 있습니다 .4 Performance OptionsP3 Overlay File System

그러면 FS는 읽기 전용이지만 쓰기는 가능합니다(종료하거나 다시 시작하면 모든 변경 사항이 손실됩니다).

당신은 읽을 수있다라스피 구성자세한 내용은 스크립트입니다.

답변4

그냥 설정이 StateDirectory=나에게 효과적입니다. 시스템 파일을 편집하는 대신 다음과 같은 몇 줄을 추가할 수 있습니다 /etc/systemd/system/systemd-timesyncd.service.d/local-allow-readonly.conf.

[Service]
StateDirectory=

디렉터리/파일 경로는 하드코딩되어 있습니다.시간동기화 프로그램User=systemd-timesync이므로 systemd-timesyncd가 디렉터리 자체를 생성할 수 없다는 점을 제외하고는 많이 변경되지 않습니다 . 그래서,

  • systemd-timesync가 처음 실행되기 전에(예: 초기 설정 스크립트에서) 이 작업을 수행하면 디렉터리(및 시계 파일)가 생성되지 않습니다.
  • 디렉토리를 생성한 후 이 작업을 수행하면 파일 시스템이 읽기/쓰기로 마운트되는 동안 시계 파일을 업데이트할 수 있습니다.

(오류가 어디서 발생하는지 궁금하다면chmod를 사용해 보세요모드가 원하는 모드로 설정되어 있어도 EROFS가 실패합니다. PrivateTmp및 와는 아무 관련이 없는 것 같습니다 CapabilityBoundingSet. )

관련 정보