fshalt 2.9 KB

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