Skip to content

fix: OTA 업데이트 시 ETXTBSY (Text file busy) 회피#1

Merged
BitByte08 merged 1 commit into
mainfrom
fix/update-script-etxtbsy
Jun 4, 2026
Merged

fix: OTA 업데이트 시 ETXTBSY (Text file busy) 회피#1
BitByte08 merged 1 commit into
mainfrom
fix/update-script-etxtbsy

Conversation

@BitByte08

Copy link
Copy Markdown
Owner

문제

/opt/{cluster,entertainment}/update.sh 실행 시 다음 에러로 업데이트 실패:

cp: cannot create regular file '/opt/entertainment/entertainment': Text file busy

원인

  1. TMP_BINARY=/tmp/... — tmpfs(/tmp)와 rootfs(/opt)는 다른 파일시스템.
  2. 기존 로직: mv $OLD $OLD.oldcp $TMP $TARGET.
    • cp는 destination을 O_WRONLY로 열기 때문에 실행 중 ELF에 대해 ETXTBSY.
  3. entertainment-kiosk.serviceRestart=always + RestartSec=3 때문에 systemctl stop 직후 3초 내 재시작되어 cp와 레이스 발생.

해결

  • 임시 파일을 같은 파일시스템(${INSTALL_DIR}/.${BINARY_NAME}.new)에 받음.
  • cp + mv .old 대신 mv -f 한 번으로 atomic 교체.
    • 같은 fs 내 mv = rename(2) 시스템콜.
    • rename(2)은 실행 중 ELF에 대해서도 ETXTBSY 없이 inode 포인터를 교체. 실행 중인 프로세스는 unlinked 된 옛 inode를 그대로 사용하다 종료 후 systemd가 새 바이너리로 재시작.
  • 서비스명 상수화(SERVICE_NAME)로 가독성 개선.
  • mv 실패 시 명시적 에러 분기 추가.

영향 범위

  • scripts/update.sh (Cluster Pi)
  • scripts/entertainment-update.sh (Entertainment Pi)

두 스크립트가 동일한 버그를 갖고 있어 함께 패치.

수동 검증

  • bash -n 문법 통과.
  • Entertainment Pi에서 같은 mv 트릭(수동 핫스왑)으로 v0.0.13 적용 성공 확인.

후속

이 PR 머지 후 v0.0.14 태그 푸시 → release.yml 자동 릴리스.

다운로드 임시 경로를 /tmp(별도 fs)에서 INSTALL_DIR(..new)로
이동해 같은 파일시스템 내 mv가 rename(2)로 동작하도록 변경.
rename(2)은 실행 중 ELF에 대해서도 atomic 치환이 보장되므로
Restart=always 서비스에서 stop과 systemd 재시작 사이의 레이스로
'cp: Text file busy' 가 나던 문제 해결.

- TMP_BINARY: /tmp/... → ${INSTALL_DIR}/.${BINARY_NAME}.new
- cp + mv .old 패턴 → mv -f (atomic rename) 한 번으로 교체
- 서비스명 상수화 (SERVICE_NAME)
- mv 실패 시 명시적 에러 분기 추가

scripts/update.sh(cluster), scripts/entertainment-update.sh 동일 패치.
@BitByte08 BitByte08 merged commit 231ff2d into main Jun 4, 2026
1 check passed
@BitByte08 BitByte08 deleted the fix/update-script-etxtbsy branch June 4, 2026 00:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant