xref: /plan9/rc/bin/fshalt (revision 15bfe97de97771872f389e30cbf1ae2973fc2dfe)
17a3484c3SDavid du Colombier#!/bin/rc
24e3613abSDavid du Colombier# fshalt [-r] [new-kernel] - sync (flush) and, if possible, halt all
34e3613abSDavid du Colombier#	file servers and optionally reboot
481bcec06SDavid du Colombierrfork nes
54e3613abSDavid du Colombierkern=()
6e332dd3eSDavid du Colombierkerncopy=()
76b0d5c8bSDavid du Colombierreboot=no
84e3613abSDavid du Colombierfn usage {
94e3613abSDavid du Colombier	echo usage: $1 '[-r] [new-kernel]' >[1=2]
104e3613abSDavid du Colombier	exit usage
114e3613abSDavid du Colombier}
124e3613abSDavid du Colombierif (! ~ $#* 0)
134e3613abSDavid du Colombier	switch ($1) {
144e3613abSDavid du Colombier	case -r
154e3613abSDavid du Colombier		reboot=yes
164e3613abSDavid du Colombier		shift
174e3613abSDavid du Colombier	case -*
184e3613abSDavid du Colombier		usage $0
194e3613abSDavid du Colombier	}
206b0d5c8bSDavid du Colombierswitch ($#*) {
216b0d5c8bSDavid du Colombiercase 0
226b0d5c8bSDavid du Colombiercase 1
234e3613abSDavid du Colombier	kern = $1
246b0d5c8bSDavid du Colombiercase *
254e3613abSDavid du Colombier	usage $0
266b0d5c8bSDavid du Colombier}
276b0d5c8bSDavid du Colombier
287a3484c3SDavid du Colombierpath=(/bin)
297a3484c3SDavid du Colombierbuiltin cd /
30e332dd3eSDavid du Colombier9fs boot		# in case of odd namespace
31e332dd3eSDavid du Colombierramfs			# stash files here that we'll need after the fs halts
327a3484c3SDavid du Colombier
33c4b21101SDavid du Colombiersetrtc
34c4b21101SDavid du Colombier
35e332dd3eSDavid du Colombier# turn off graphics, if any
36e332dd3eSDavid du Colombierif (test -e '#v/vgactl' && test -e '#P/realmode') {
37a2ede175SDavid du Colombier	vgatype=`{read '#v/vgactl'}
38a2ede175SDavid du Colombier	if (! ~ $vgatype(2) cga) {
3984ba54caSDavid du Colombier		prompt=''
40e332dd3eSDavid du Colombier		kill rio | rc -i &
41e332dd3eSDavid du Colombier		sleep 2
42e332dd3eSDavid du Colombier		aux/vga -l text
43e332dd3eSDavid du Colombier	}
44a2ede175SDavid du Colombier}
45e332dd3eSDavid du Colombier
46e332dd3eSDavid du Colombierfn isbootable {
47*15bfe97dSDavid du Colombier	test -e $1 && ~ `{file $1} *' plan 9 boot image' \
48*15bfe97dSDavid du Colombier		*' plan 9 executable'* *ELF*' executable'
49e332dd3eSDavid du Colombier}
50e332dd3eSDavid du Colombierfn usekernel {
5181bcec06SDavid du Colombier	kerncopy=kern
5281bcec06SDavid du Colombier	cp $1 /tmp/$kerncopy && echo -n using kernel $1...
53e332dd3eSDavid du Colombier}
54e332dd3eSDavid du Colombier
55e332dd3eSDavid du Colombier# make a copy of the right kernel
56e332dd3eSDavid du Colombierif (~ $reboot yes) {
574e3613abSDavid du Colombier	if (~ $#kern 0)
58e332dd3eSDavid du Colombier		kern=`{echo $terminal |
59ad68c38aSDavid du Colombier			sed 's;^([^ ]+) .*/([^/ ]+).*$;/n/boot/'$cputype'/9\2;'}
60e332dd3eSDavid du Colombier	if (isbootable $kern)
61e332dd3eSDavid du Colombier		usekernel $kern
62e332dd3eSDavid du Colombier	if not {
63e332dd3eSDavid du Colombier		# $kern is probably a raw binary, try s^name as boot image
64e332dd3eSDavid du Colombier		kern=`{ echo $kern | sed 's;.*/;&s;' }
65e332dd3eSDavid du Colombier		if (isbootable $kern)
66e332dd3eSDavid du Colombier			usekernel $kern
67e332dd3eSDavid du Colombier		if not
68e332dd3eSDavid du Colombier			echo -n using default kernel...
69e332dd3eSDavid du Colombier	}
70e332dd3eSDavid du Colombier}
71e332dd3eSDavid du Colombier
72ebbc20e5SDavid du Colombier# start venti flushing
73ebbc20e5SDavid du Colombierventi/sync -h localhost >[2]/dev/null &
74ebbc20e5SDavid du Colombierventi/sync  >[2]/dev/null &
75ebbc20e5SDavid du Colombier
766b0d5c8bSDavid du Colombierunmount /mnt/consoles >[2]/dev/null
77c717cbbdSDavid du Colombierkill consolefs | rc			# don't compete with /mnt/consoles
78f54a2a50SDavid du Colombierkill cron | rc				# unlock /cron/lock
7970b6ec21SDavid du Colombierkill watchdog | rc
80c717cbbdSDavid du Colombiersleep 1
81c717cbbdSDavid du Colombier
827a3484c3SDavid du Colombierf=`{ls /srv/fscons*>[2]/dev/null}
837a3484c3SDavid du Colombierk=`{ls /srv/kfs*cmd >[2]/dev/null|sort -r}
847a3484c3SDavid du Colombier
857a3484c3SDavid du Colombierecho -n syncing...
864e7b9544SDavid du Colombierfor(i in $f) @ {
877a3484c3SDavid du Colombier	echo -n $i...
887a3484c3SDavid du Colombier	{
89ce31847cSDavid du Colombier		echo
90ebbc20e5SDavid du Colombier		dial/drain &
91ebbc20e5SDavid du Colombier		sleep 2
927a3484c3SDavid du Colombier		echo fsys all sync
93c89dfd4eSDavid du Colombier		if(! dial/expect -t 120 ': ')
947a3484c3SDavid du Colombier			echo -n 'not synced...' > /dev/cons
95220e960cSDavid du Colombier	} < $i >> $i
967a3484c3SDavid du Colombier}
977a3484c3SDavid du Colombier
98ebbc20e5SDavid du Colombier# flush the last bit of possible fossil traffic
99a3fbd160SDavid du Colombierif (ls /srv | grep -s fossil) {
1007a3484c3SDavid du Colombier	echo -n venti...
101ebbc20e5SDavid du Colombier	venti/sync -h localhost >[2]/dev/null &
102059f8267SDavid du Colombier	venti/sync  >[2]/dev/null &
103f05caca4SDavid du Colombier	sleep 5
104a3fbd160SDavid du Colombier}
1057a3484c3SDavid du Colombier
1067a3484c3SDavid du Colombierfor (i in $k){
107ef53e415SDavid du Colombier	echo -n $i...
108ef53e415SDavid du Colombier	switch($i){
109ef53e415SDavid du Colombier	case /srv/kfs.cmd
110ef53e415SDavid du Colombier		disk/kfscmd sync
111ef53e415SDavid du Colombier	case *
112ef53e415SDavid du Colombier		disk/kfscmd -n `{echo $i | sed -n 's%/srv/kfs.(.*).cmd%\1%p'} sync
113ef53e415SDavid du Colombier	}
1147a3484c3SDavid du Colombier	sleep 2
1157a3484c3SDavid du Colombier}
1167a3484c3SDavid du Colombier
1177a3484c3SDavid du Colombier# halting (binaries we run can't be on the fs we're halting)
118e332dd3eSDavid du Colombierbuiltin cd /bin
119e332dd3eSDavid du Colombiercp dial/expect echo disk/kfscmd rc sed /tmp
1207a3484c3SDavid du Colombierbuiltin cd /tmp
121c89dfd4eSDavid du Colombiermkdir /tmp/lib
122c89dfd4eSDavid du Colombiercp /rc/lib/rcmain /tmp/lib
123c89dfd4eSDavid du Colombierbind /tmp /rc
1247a3484c3SDavid du Colombierbind /tmp /bin
1257a3484c3SDavid du Colombier
126c89dfd4eSDavid du Colombier# put this in a shell function so this rc script doesn't get read
127c89dfd4eSDavid du Colombier# when it's no longer accessible
128c89dfd4eSDavid du Colombierfn x {
129a3fbd160SDavid du Colombier	rfork s
1307a3484c3SDavid du Colombier	echo
1317a3484c3SDavid du Colombier	echo -n halting...
1324e7b9544SDavid du Colombier	for(i in $f) @ {
1337a3484c3SDavid du Colombier		echo -n $i...
1347a3484c3SDavid du Colombier		{
1357a3484c3SDavid du Colombier			echo fsys all halt
136c89dfd4eSDavid du Colombier			if(! expect -t 60 ': ')
1377a3484c3SDavid du Colombier				echo -n 'not halted...' > /dev/cons
138220e960cSDavid du Colombier		} < $i >> $i
1397a3484c3SDavid du Colombier	}
1407a3484c3SDavid du Colombier
1417a3484c3SDavid du Colombier	for (i in $k){
1427a3484c3SDavid du Colombier		echo -n $i...
143ef53e415SDavid du Colombier		switch($i){
144ef53e415SDavid du Colombier		case /srv/kfs.cmd
145ef53e415SDavid du Colombier			kfscmd halt
146ef53e415SDavid du Colombier		case *
147ef53e415SDavid du Colombier			kfscmd -n `{echo $i | sed -n 's%/srv/kfs.(.*).cmd%\1%p'} halt
148ef53e415SDavid du Colombier		}
1497a3484c3SDavid du Colombier	}
1507a3484c3SDavid du Colombier	echo
1516b0d5c8bSDavid du Colombier	echo done halting
1526b0d5c8bSDavid du Colombier
153e332dd3eSDavid du Colombier	if (~ $reboot yes)
15481bcec06SDavid du Colombier		echo reboot $kerncopy >'#c/reboot'
155c89dfd4eSDavid du Colombier}
156c89dfd4eSDavid du Colombier
157c89dfd4eSDavid du Colombierx
158