以下には、いくつかのファイルシステムのメンテナンスを試みるテストスクリプトがあります。これは単なる単純な部分です。 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
アンインストールされ、システムログには次のものが含まれます。
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
これがまさに私が期待したものです。ナビゲーションを通じてWeb上で実行できます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