mirror of
git://git.9front.org/plan9front/plan9front
synced 2025-01-12 11:10:06 +00:00
390c71f0c7
MNT Reform's power rails are switched off abruptly on shutdown which causes an "unsafe" shutdown on nvme. This may result in loss of valid data in the volatile write cache, which is never going to be synced in this case. This problem has been reported on forums about Linux too, including actual filesystem errors resulting from that behavior. Notify nvme about a shutdown and wait up to 3s before disabling the controller. This resulted in "unsafe shutdowns" nvme's counter to never increase on fshalt.
97 lines
1.8 KiB
Bash
Executable file
97 lines
1.8 KiB
Bash
Executable file
#!/bin/rc
|
|
# fshalt [-r [kernel]] - sync (flush) and, if possible, halt all file servers
|
|
# and optionally reboot
|
|
rfork en
|
|
reboot=no
|
|
scram=no
|
|
bootf=()
|
|
if(~ $1 -r){
|
|
reboot=yes
|
|
shift
|
|
}
|
|
if not if(! ~ $#* 0 && ! ~ $#* 1){
|
|
echo usage: $0 '[-r bootkern]' >[1=2]
|
|
exit usage
|
|
}
|
|
|
|
if(~ $reboot yes && ~ $#* 1){
|
|
bootf=$1
|
|
if(! ~ $bootf /*)
|
|
bootf=`{builtin pwd}^/$bootf
|
|
}
|
|
|
|
path=(/bin)
|
|
builtin cd /
|
|
bind -c '#s' /srv
|
|
bind '#p' /proc
|
|
|
|
unmount /mnt/consoles >[2]/dev/null
|
|
kill consolefs | rc # don't compete with /mnt/consoles
|
|
sleep 1
|
|
|
|
c=`{ls /srv/cwfs*cmd >[2]/dev/null}
|
|
h=`{ls /srv/hjfs*cmd >[2]/dev/null}
|
|
s=`{awk '/^sd./ {print substr($1,3,1)}' <'#S/sdctl' >[2]/dev/null}
|
|
|
|
# for scram, don't scram other systems
|
|
bind -b '#P' /dev >[2]/dev/null
|
|
if(! ~ $reboot yes){
|
|
if(test -e '#P'/apm)
|
|
scram=yes
|
|
if(test -e '#P'/acpitbls -a -e '#P'/iow)
|
|
scram=yes
|
|
}
|
|
|
|
# halting (binaries we run can't be on the fs we're halting)
|
|
ramfs
|
|
builtin cd /tmp
|
|
cp /bin/echo /tmp
|
|
mkdir /tmp/lib
|
|
cp /rc/lib/rcmain /tmp/lib
|
|
cp /bin/ns /tmp
|
|
cp /bin/rc /tmp
|
|
cp /bin/sed /tmp
|
|
cp /bin/sleep /tmp
|
|
cp /bin/scram /tmp
|
|
cp /bin/test /tmp
|
|
if(~ $#bootf 1){
|
|
if(! cp $bootf /tmp/bootf)
|
|
exit 'failed to copy kernel'
|
|
bootf=/bin/bootf
|
|
}
|
|
bind /tmp /rc
|
|
bind /tmp /bin
|
|
|
|
# put this in a shell function so this rc script doesn't get read
|
|
# when it's no longer accessible
|
|
fn x {
|
|
echo
|
|
echo -n halting...
|
|
for(i in $c $h)
|
|
echo halt >>$i
|
|
for(i in $c $h){
|
|
echo -n $i...
|
|
while(test -e $i)
|
|
sleep 1
|
|
}
|
|
echo
|
|
echo done halting
|
|
|
|
# turn off disk drives
|
|
for(i in $s)
|
|
echo config spec $i switch off >>'#S/sdctl'
|
|
|
|
if(~ $reboot yes){
|
|
echo rebooting...
|
|
echo reboot $bootf >'#c/reboot'
|
|
}
|
|
if not {
|
|
if (test -e /dev/pmctl)
|
|
echo power off >>/dev/pmctl
|
|
if (~ $scram yes)
|
|
scram
|
|
echo 'It''s now safe to turn off your computer'
|
|
}
|
|
}
|
|
|
|
x
|