1#!/bin/rc 2# fshalt [-r] [new-kernel] - sync (flush) and, if possible, halt all 3# file servers and optionally reboot 4rfork nes 5kern=() 6kerncopy=() 7reboot=no 8fn usage { 9 echo usage: $1 '[-r] [new-kernel]' >[1=2] 10 exit usage 11} 12if (! ~ $#* 0) 13 switch ($1) { 14 case -r 15 reboot=yes 16 shift 17 case -* 18 usage $0 19 } 20switch ($#*) { 21case 0 22case 1 23 kern = $1 24case * 25 usage $0 26} 27 28path=(/bin) 29builtin cd / 309fs boot # in case of odd namespace 31ramfs # stash files here that we'll need after the fs halts 32 33setrtc 34 35# turn off graphics, if any 36if (test -e '#v/vgactl' && test -e '#P/realmode') { 37 vgatype=`{read '#v/vgactl'} 38 if (! ~ $vgatype(2) cga) { 39 prompt='' 40 kill rio | rc -i & 41 sleep 2 42 aux/vga -l text 43 } 44} 45 46fn isbootable { 47 test -e $1 && ~ `{file $1} *' plan 9 boot image' \ 48 *' plan 9 executable'* *ELF*' executable' 49} 50fn usekernel { 51 kerncopy=kern 52 cp $1 /tmp/$kerncopy && echo -n using kernel $1... 53} 54 55# make a copy of the right kernel 56if (~ $reboot yes) { 57 if (~ $#kern 0) 58 kern=`{echo $terminal | 59 sed 's;^([^ ]+) .*/([^/ ]+).*$;/n/boot/'$cputype'/9\2;'} 60 if (isbootable $kern) 61 usekernel $kern 62 if not { 63 # $kern is probably a raw binary, try s^name as boot image 64 kern=`{ echo $kern | sed 's;.*/;&s;' } 65 if (isbootable $kern) 66 usekernel $kern 67 if not 68 echo -n using default kernel... 69 } 70} 71 72# start venti flushing 73venti/sync -h localhost >[2]/dev/null & 74venti/sync >[2]/dev/null & 75 76unmount /mnt/consoles >[2]/dev/null 77kill consolefs | rc # don't compete with /mnt/consoles 78kill cron | rc # unlock /cron/lock 79kill watchdog | rc 80sleep 1 81 82f=`{ls /srv/fscons*>[2]/dev/null} 83k=`{ls /srv/kfs*cmd >[2]/dev/null|sort -r} 84 85echo -n syncing... 86for(i in $f) @ { 87 echo -n $i... 88 { 89 echo 90 dial/drain & 91 sleep 2 92 echo fsys all sync 93 if(! dial/expect -t 120 ': ') 94 echo -n 'not synced...' > /dev/cons 95 } < $i >> $i 96} 97 98# flush the last bit of possible fossil traffic 99if (ls /srv | grep -s fossil) { 100 echo -n venti... 101 venti/sync -h localhost >[2]/dev/null & 102 venti/sync >[2]/dev/null & 103 sleep 5 104} 105 106for (i in $k){ 107 echo -n $i... 108 switch($i){ 109 case /srv/kfs.cmd 110 disk/kfscmd sync 111 case * 112 disk/kfscmd -n `{echo $i | sed -n 's%/srv/kfs.(.*).cmd%\1%p'} sync 113 } 114 sleep 2 115} 116 117# halting (binaries we run can't be on the fs we're halting) 118builtin cd /bin 119cp dial/expect echo disk/kfscmd rc sed /tmp 120builtin cd /tmp 121mkdir /tmp/lib 122cp /rc/lib/rcmain /tmp/lib 123bind /tmp /rc 124bind /tmp /bin 125 126# put this in a shell function so this rc script doesn't get read 127# when it's no longer accessible 128fn x { 129 rfork s 130 echo 131 echo -n halting... 132 for(i in $f) @ { 133 echo -n $i... 134 { 135 echo fsys all halt 136 if(! expect -t 60 ': ') 137 echo -n 'not halted...' > /dev/cons 138 } < $i >> $i 139 } 140 141 for (i in $k){ 142 echo -n $i... 143 switch($i){ 144 case /srv/kfs.cmd 145 kfscmd halt 146 case * 147 kfscmd -n `{echo $i | sed -n 's%/srv/kfs.(.*).cmd%\1%p'} halt 148 } 149 } 150 echo 151 echo done halting 152 153 if (~ $reboot yes) 154 echo reboot $kerncopy >'#c/reboot' 155} 156 157x 158