fshalt 2.6 KB

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