plan9front/rc/bin/fshalt
Sigrid Solveig Haflínudóttir 390c71f0c7 sdnvme, fshalt: turn disks off on fshalt
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.
2023-05-24 16:14:33 +00:00

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