아래에는 일부 파일 시스템 유지 관리를 시도하는 테스트 스크립트가 있습니다. 이것은 단지 간단한 조각입니다. LVM 논리 볼륨(마운트된)을 마운트 해제하고 /data
장치에서 실행합니다. e2fsck
스크립트는 Apache를 통해 원격으로 실행되어야 합니다.
문제는 원격으로 로그인하여 사용자로 수동으로 실행할 때 www-data
스크립트가 작동 하지만 Apache가 실행할 때는 작동하지 않는다는 것입니다.. Apache가 이를 실행하면 스크립트는 성공적으로 제거되었다고 생각 /data
하지만 e2fsck
장치가 여전히 사용 중이라고 생각하기 때문에 실패합니다. 그러나 테스트에는 fuser
아무 것도 표시되지 않으며 스크립트가 종료될 때 장치는 여전히 마운트되어 있습니다.
다음과 같이 수동으로 실행합니다.
root@vserver # su www-data -s /bin/bash
www-data@vserver $ cfg-test.sh
Status: 200 OK
Content-type: text/html
<p>Completed Ok.</p>
완료되면 원격 시스템의 상태는 예상대로 /data
Uninstalled가 되며 시스템 로그에는 다음이 포함됩니다.
Jan 23 15:51:26 vserver cfg-test.sh: Restarting as root
Jan 23 15:51:26 vserver cfg-test.sh: Unmounting /data...
Jan 23 15:51:27 vserver cfg-test.sh: Unmount succeeded; ll /data: (total 0)
Jan 23 15:51:27 vserver cfg-test.sh: e2fsck Ok
이것이 바로 제가 기대했던 것입니다. 탐색을 통해 웹에서 실행할 수 있습니다 https://vserver/cfg-test.sh
. 그러나 이는 작동하지 않습니다. 브라우저는 Terminated with code 3. See the syslog for details.
시스템 로그에 다음을 표시한다고 보고합니다.
Jan 23 15:48:49 vserver cfg-test.sh: Restarting as root
Jan 23 15:48:49 vserver cfg-test.sh: Unmounting /data...
Jan 23 15:48:49 vserver cfg-test.sh: Unmount succeeded; ll /data: (total 0)
Jan 23 15:48:49 vserver cfg-test.sh: fuser -c /dev/mapper/vg0-data: ()
Jan 23 15:48:49 vserver cfg-test.sh: e2fsck failed; terminating (/dev/mapper/vg0-data is in use.#012e2fsck: Cannot continue, aborting.) (/dev/mapper/vg0-data)
그러나 그들은 umount
그렇습니다아니요성공했습니다. /data
여전히 원격 서버에 설치되어 있습니다. 이 결과가 스크립트를 수동으로 실행하는 것과 다른 이유는 무엇입니까? 관련이 있는 경우 원격은 Ubuntu 22.04 VM입니다. 스크립트는 sudoers
비밀번호 없이 실행할 수 있는 파일에 있습니다 .www-data
#!/bin/bash
scriptname=$(basename "$0")
dev=/dev/mapper/vg0-data
retcode=0
# log messages to syslog
log() {
if (($# < 1)); then
return
fi
msg="$1"
shift
while (($# > 0))
do
msg+=" ($1)"
shift
done
logger -t "$scriptname" "$msg"
}
if ((EUID > 0)); then
log "Restarting as root"
exec sudo "$0" "$@"
fi
while true ; do
log "Unmounting /data..."
output=$(umount -vvv --force /data 2>&1)
code=$?
if ((code > 0)); then
log "umount /data failed; terminating" "$code" "$output"
log "ll /data:" "$(ls -l /data)"
retcode=1
break
fi
# check mount's output
if output=$(mount | grep "$dev" 2>&1); then
log "/data is still mounted!" "$output"
log "ll /data:" "$(ls -l /data)"
retcode=2
break
fi
# exit codes 0 and 1 are both Ok
log "Unmount succeeded; ll /data:" "$(ls -l /data)"
output=$(e2fsck -p -f "$dev" 2>&1)
if (($? > 1)); then
log "fuser -c $dev:" "$(fuser -c $dev)"
log "e2fsck failed; terminating" "$output" "$dev"
retcode=3
break
fi
log "e2fsck Ok"
break
done
if ((retcode == 0)); then
echo "Status: 200 OK"
echo "Content-type: text/html"
echo ""
echo "<p>Completed Ok.</p>"
else
echo "Status: 400 Bad Request"
echo "Content-type: text/html"
echo ""
echo "<p>Terminated with code $retcode. See the syslog for details.</p>"
fi