1#!/bin/sh
2#############################################################################
3#
4# ipmi:		OpenIPMI Driver helper script
5#
6# Authors:	Jan Safranek <jsafrane@redhat.com>
7#
8# Based on IPMI init script by:
9#               Matt Domsch <Matt_Domsch@dell.com>
10#               Chris Poblete <Chris_Poblete@dell.com>
11#
12# Status return code bits
13# no bits set = no errors
14# bit 0 set = minimum modules aren't loaded
15# bit 1 set = requested feature module isn't loaded
16# bit 2 set = /dev/ipmi0 (or /dev/imb if using that instead) doesn't exist
17# bit 3 set = /dev/watchdog doesn't exist
18# bit 4 set = lockfile doesn't exist
19# bit 5 set = modules are loaded even when asked to be unloaded
20
21CONFIGFILE=/etc/sysconfig/ipmi
22# source config info
23[ -r ${CONFIGFILE} ] && . ${CONFIGFILE}
24
25#############################################################################
26# GLOBALS
27#############################################################################
28MODULE_NAME="ipmi"
29INTF_NUM=0
30
31IPMI_SMB_MODULE_NAME="ipmi_smb"
32IPMI_SI_MODULE_NAME="ipmi_si"
33kernel=`uname -r | cut -d. -f1-2`
34if [ "${kernel}" == "2.4" ]; then
35    IPMI_SMB_MODULE_NAME="ipmi_smb_intf"
36    IPMI_SI_MODULE_NAME="ipmi_si_drv"
37fi
38
39MODULES_INTERFACES=""
40[ "${DEV_IPMI}" = "yes" ] && MODULES_INTERFACES="${MODULES_INTERFACES} ipmi_devintf"
41[ "${IPMI_IMB}" = "yes" ] && MODULES_INTERFACES="${MODULES_INTERFACES} ipmi_imb"
42
43MODULES_FEATURES=""
44[ "${IPMI_WATCHDOG}" = "yes" ] && MODULES_FEATURES="${MODULES_FEATURES} ipmi_watchdog"
45[ "${IPMI_POWEROFF}" = "yes" ] && MODULES_FEATURES="${MODULES_FEATURES} ipmi_poweroff"
46
47MODULES_HW=""
48[ "${IPMI_SI}"  = "yes" ] && MODULES_HW="${MODULES_HW} ${IPMI_SI_MODULE_NAME}"
49[ "${IPMI_SMB}" = "yes" ] && MODULES_HW="${MODULES_HW} ${IPMI_SMB_MODULE_NAME}"
50
51MODULES_BASE="ipmi_msghandler"
52MODULES="${MODULES_INTERFACES} ${MODULES_FEATURES} ${MODULES_HW} ${MODULES_BASE}"
53
54RETVAL=0
55LOCKFILE=/var/lock/subsys/ipmi
56DEV_IPMI_TIMEOUT=150
57
58UDEV_EXISTS=0
59if [ -e /sbin/udev -o -e /sbin/udevd ]; then
60    UDEV_EXISTS=1
61fi
62
63#############################################################################
64# NOTES:
65# * /dev/ipmi0 is unconditionally deleted here on ipmi_devintf unload,
66#   because SLES9 and RHEL4 kernels don't send a message for udev to delete
67#   it for us.
68#
69#############################################################################
70
71modules_loaded_verbose()
72{
73	OnePlusLoaded=0
74	OnePlusUnloaded=0
75	for m in $@; do
76		if /sbin/lsmod | grep $m >/dev/null 2>&1 ; then
77			echo "$m module loaded."
78			OnePlusLoaded=1
79		else
80			echo "$m module not loaded."
81			OnePlusUnloaded=1
82		fi
83	done
84}
85
86modules_loaded()
87{
88	OnePlusLoaded=0
89	OnePlusUnloaded=0
90	for m in $@; do
91		if /sbin/lsmod | grep $m >/dev/null 2>&1 ; then
92			OnePlusLoaded=1
93		else
94			OnePlusUnloaded=1
95		fi
96	done
97}
98
99device_node_exists ()
100{
101	if [ -e "$1" ]; then
102		echo "$1 exists."
103		return 1
104	fi
105	echo "$1 does not exist."
106	return 0
107}
108
109minimum_modules_loaded()
110{
111        rc_base=1
112	rc_hw=1
113        modules_loaded_verbose "${MODULES_BASE}"
114	[ ${OnePlusLoaded} -eq 0 ] && rc_base=0
115
116	modules_loaded_verbose "${MODULES_HW}"
117	[ ${OnePlusLoaded} -eq 0 ] && rc_hw=0
118
119	return $((rc_base && rc_hw))
120}
121
122#############################################################################
123
124load_si()
125{
126	if [ "${IPMI_SI}" = "yes" ]; then
127		modprobe ${IPMI_SI_MODULE_NAME} > /dev/null 2>&1
128		modules_loaded ${IPMI_SI_MODULE_NAME}
129		[ ${OnePlusLoaded} -ne 1 ] && RETVAL=$((RETVAL | 1))
130	fi
131}
132
133load_smb()
134{
135	if [ "${IPMI_SMB}" = "yes" ]; then
136		modprobe ${IPMI_SMB_MODULE_NAME} > /dev/null 2>&1
137		modules_loaded ${IPMI_SMB_MODULE_NAME}
138		[ ${OnePlusLoaded} -ne 1 ] && RETVAL=$((RETVAL | 1))
139	fi
140}
141
142load_hw_modules()
143{
144	load_si
145	load_smb
146}
147
148start_watchdog_common()
149{
150	load_hw_modules
151	modprobe ipmi_watchdog ${IPMI_WATCHDOG_OPTIONS} > /dev/null 2>&1
152	modules_loaded ipmi_watchdog
153	[ ${OnePlusUnloaded} -ne 0 ] &&
154		RETVAL=$((RETVAL | 2)) &&
155		echo "Watchdog startup failed: cannot load ipmi_watchdog module" &&
156		return
157	if [ ${UDEV_EXISTS} -eq 0 -a ! -e /dev/watchdog ]; then
158		mknod -m 0600 /dev/watchdog c 10 130
159		[ $? -ne 0 ] &&
160			RETVAL=$((RETVAL | 8)) &&
161			echo "Watchdog startup failed: cannot create /dev/watchdog" &&
162			return
163	fi
164}
165
166start_watchdog_quiet()
167{
168	[ "${IPMI_WATCHDOG}" != "yes" ] &&
169		return
170	start_watchdog_common
171}
172
173start_watchdog()
174{
175	[ "${IPMI_WATCHDOG}" != "yes" ] &&
176		RETVAL=$((RETVAL | 2)) &&
177		echo "Watchdog not configured" &&
178		return
179	start_watchdog_common
180}
181
182stop_watchdog()
183{
184	modprobe -q -r ipmi_watchdog > /dev/null 2>&1
185	modules_loaded ipmi_watchdog
186	if [ ${OnePlusLoaded} -ne 0 ]; then
187	    RETVAL=$((RETVAL | 32))
188	    echo "Watchog shutdown failed: cannot unload ipmi_watchdog module"
189	else
190	    if [ "${IPMI_WATCHDOG}" = "yes" ]; then
191		[ ${UDEV_EXISTS} -eq 0 ] && rm -f /dev/watchdog
192	    fi
193	fi
194}
195
196stop_watchdog_quiet()
197{
198	modprobe -q -r ipmi_watchdog > /dev/null 2>&1
199	modules_loaded ipmi_watchdog
200	if [ ${OnePlusLoaded} -ne 0 ]; then
201	    RETVAL=$((RETVAL | 32))
202	else
203	    if [ "${IPMI_WATCHDOG}" = "yes" ]; then
204		[ ${UDEV_EXISTS} -eq 0 ] && rm -f /dev/watchdog
205	    fi
206	fi
207}
208
209start_powercontrol_common()
210{
211	local poweroff_opts=""
212	load_hw_modules
213	if [ "${IPMI_POWERCYCLE}" == "yes" ]; then
214	    modinfo ipmi_poweroff 2>/dev/null | grep poweroff_control > /dev/null 2>&1 && \
215		poweroff_opts="poweroff_control=2"
216	    modinfo ipmi_poweroff 2>/dev/null | grep poweroff_powercycle > /dev/null 2>&1 && \
217		poweroff_opts="poweroff_powercycle=1"
218	fi
219	modprobe ipmi_poweroff "${poweroff_opts}" > /dev/null 2>&1
220	modules_loaded ipmi_poweroff
221	[ ${OnePlusUnloaded} -ne 0 ] &&
222		RETVAL=$((RETVAL | 2)) &&
223		echo "Powercontroll startup failed: cannot load ipmi_poweroff module" &&
224		return
225}
226
227start_powercontrol_quiet()
228{
229	[ "${IPMI_POWEROFF}" != "yes" ] &&
230		return
231	start_powercontrol_common
232}
233
234start_powercontrol()
235{
236	[ "${IPMI_POWEROFF}" != "yes" ] &&
237		RETVAL=$((RETVAL | 2)) &&
238		echo "Powercontroll not configured" &&
239		return
240	start_powercontrol_common
241}
242
243stop_powercontrol()
244{
245	modprobe -q -r ipmi_poweroff > /dev/null 2>&1
246	modules_loaded ipmi_poweroff
247	if [ ${OnePlusLoaded} -ne 0 ]; then
248	    RETVAL=$((RETVAL | 32))
249	    echo "Powercontroll shutdown failed: cannot unload ipmi_poweroff module"
250	fi
251}
252
253stop_powercontrol_quiet()
254{
255	modprobe -q -r ipmi_poweroff > /dev/null 2>&1
256	modules_loaded ipmi_poweroff
257	[ ${OnePlusLoaded} -ne 0 ] && RETVAL=$((RETVAL | 32))
258}
259
260#############################################################################
261unload_all_ipmi_modules()
262{
263	stop_watchdog_quiet
264	stop_powercontrol_quiet
265	for m in ${MODULES}; do
266		modprobe -q -r ${m} > /dev/null 2>&1
267	done
268        # delete interface node ONLY if ipmi_devintf is unloaded
269        [ `lsmod | grep -c "ipmi_devintf"` -eq 0 ] &&
270	        rm -f "/dev/ipmi${INTF_NUM}"
271}
272
273unload_ipmi_modules_leave_features()
274{
275	for m in ${MODULES_INTERFACES}; do
276		modprobe -q -r ${m} > /dev/null 2>&1
277	done
278        # delete interface node ONLY if ipmi_devintf is unloaded
279        [ `lsmod | grep -c "ipmi_devintf"` -eq 0 ] &&
280	        rm -f "/dev/ipmi${INTF_NUM}"
281	lsmod | egrep -q "ipmi_(poweroff|watchdog)" > /dev/null 2>&1
282	if [ "$?" -ne "0" ]; then
283		stop_watchdog_quiet
284		stop_powercontrol_quiet
285		for m in ${MODULES}; do
286			modprobe -q -r ${m} > /dev/null 2>&1
287		done
288	fi
289}
290
291#############################################################################
292load_ipmi_modules ()
293{
294	local locdelay
295	modprobe ipmi_msghandler > /dev/null 2>&1
296	modules_loaded ipmi_msghandler
297	[ ${OnePlusLoaded} -ne 1 ] && unload_all_ipmi_modules && RETVAL=$((RETVAL | 1)) && return
298	load_hw_modules
299	[ $((RETVAL & 1)) -eq 1 ] && unload_all_ipmi_modules && RETVAL=$((RETVAL | 1)) && return
300
301	if [ "${DEV_IPMI}" = "yes" ]; then
302		modprobe ipmi_devintf > /dev/null 2>&1
303		modules_loaded ipmi_devintf
304		RETVAL=$((RETVAL & ~2))
305		[ ${OnePlusLoaded} -eq 0 ] && RETVAL=$((RETVAL | 2))
306		if [ ${OnePlusLoaded} -eq 1 ]; then
307			if [ ${UDEV_EXISTS} -eq 0 ]; then
308				DEVMAJOR=`cat /proc/devices | awk '/ipmidev/{print $1}'`
309				rm -f /dev/ipmi${INTF_NUM}
310				mknod -m 0600 /dev/ipmi${INTF_NUM} c ${DEVMAJOR} 0 || RETVAL=$((RETVAL | 4))
311			fi
312
313			# udev can take several seconds to create /dev/ipmi0,
314			# but it happens asynchronously, so delay here
315			locdelay=${DEV_IPMI_TIMEOUT}
316			while [ ! -e /dev/ipmi${INTF_NUM} -a ${locdelay} -gt 0 ]; do
317				locdelay=$((locdelay - 1))
318				sleep 0.1
319			done
320		fi
321	fi
322
323	if [ "${IPMI_IMB}" = "yes" ]; then
324		modprobe ipmi_imb > /dev/null 2>&1
325		modules_loaded ipmi_imb
326		RETVAL=$((RETVAL & ~2))
327		[ ${OnePlusLoaded} -eq 0 ] && RETVAL=$((RETVAL | 2))
328		if [ ${OnePlusLoaded} -eq 1 ]; then
329			DEVMAJOR=`cat /proc/devices | awk '/imb/{print $1}'`
330			rm -f /dev/imb
331			mknod -m 0600 /dev/imb c ${DEVMAJOR} 0 || RETVAL=$((RETVAL | 4))
332		fi
333	fi
334
335	# Per Corey Minyard, essentially no one uses ipmi_radisys
336	# and we don't want to encourage its further use
337	# so it won't be handled here.
338	return
339}
340
341#############################################################################
342start()
343{
344	load_ipmi_modules
345	if [ ${RETVAL} -eq 0 ]; then
346		touch ${LOCKFILE}
347	else
348		if [ $((RETVAL & 1)) -eq 1 ]; then
349			echo "Startup failed."
350		else
351			touch ${LOCKFILE} && echo "Warning!?"
352		fi
353	fi
354	start_watchdog_quiet
355	start_powercontrol_quiet
356}
357
358#############################################################################
359stop()
360{
361	unload_ipmi_modules_leave_features
362	modules_loaded ${MODULES_INTERFACES}
363	if [ ${OnePlusLoaded} -ne 0 ]; then
364		RETVAL=$((RETVAL | 32))
365		echo "Shutdown failed, something may be in use"
366	else
367		rm -f ${LOCKFILE}
368	fi
369}
370
371stop_all()
372{
373	unload_all_ipmi_modules
374	modules_loaded ${MODULES}
375	if [ ${OnePlusLoaded} -ne 0 ]; then
376		RETVAL=$((RETVAL | 32))
377		echo "Shutdown failed, something may be in use"
378	else
379		rm -f ${LOCKFILE}
380	fi
381}
382
383#############################################################################
384restart()
385{
386	stop_all
387	RETVAL=0
388	start
389}
390
391#############################################################################
392
393reload()
394{
395	stop_all
396	RETVAL=0
397	start
398}
399
400#############################################################################
401
402status_all()
403{
404	minimum_modules_loaded
405	[ $? -eq 0 ] && RETVAL=$((RETVAL | 1))
406
407	modules_loaded_verbose ${MODULES_FEATURES} ${MODULES_INTERFACES}
408	[ ${OnePlusUnloaded} -ne 0 ] && RETVAL=$((RETVAL | 2))
409
410	if [ "${DEV_IPMI}" = "yes" ]; then
411	    device_node_exists /dev/ipmi${INTF_NUM}
412	    [ $? -eq 0 ] && RETVAL=$((RETVAL | 4))
413	fi
414
415	if [ "${IPMI_IMB}" = "yes" ]; then
416	    device_node_exists /dev/imb
417	    [ $? -eq 0 ] && RETVAL=$((RETVAL | 4))
418	fi
419
420	if [ "${IPMI_WATCHDOG}" = "yes" ]; then
421	    device_node_exists /dev/watchdog
422	    [ $? -eq 0 ] && RETVAL=$((RETVAL | 8))
423	fi
424
425	[ ! -e ${LOCKFILE} ] && RETVAL=$((RETVAL | 16))
426}
427
428status()
429{
430	minimum_modules_loaded
431	[ $? -eq 0 ] && RETVAL=$((RETVAL | 1))
432
433	if [ "${DEV_IPMI}" = "yes" ]; then
434	    modules_loaded_verbose ipmi_devintf
435	    [ ${OnePlusLoaded} -eq 0 ] && RETVAL=$((RETVAL | 2))
436
437	    device_node_exists /dev/ipmi${INTF_NUM}
438	    [ $? -eq 0 ] && RETVAL=$((RETVAL | 4))
439	fi
440
441	if [ "${IPMI_IMB}" = "yes" ]; then
442	    device_node_exists /dev/imb
443	    [ $? -eq 0 ] && RETVAL=$((RETVAL | 4))
444	fi
445}
446
447status_watchdog()
448{
449	minimum_modules_loaded
450	[ $? -eq 0 ] && RETVAL=$((RETVAL | 1))
451
452	modules_loaded_verbose ipmi_watchdog
453	[ ${OnePlusLoaded} -eq 0 ] && RETVAL=$((RETVAL | 2))
454
455	device_node_exists /dev/watchdog
456	[ $? -eq 0 ] && RETVAL=$((RETVAL | 8))
457}
458
459status_powercontrol()
460{
461	minimum_modules_loaded
462	[ $? -eq 0 ] && RETVAL=$((RETVAL | 1))
463
464	modules_loaded_verbose ipmi_powercontrol
465	[ ${OnePlusLoaded} -eq 0 ] && RETVAL=$((RETVAL | 2))
466}
467
468#############################################################################
469usage ()
470{
471	echo $"Usage: $0 {start|stop|status" 1>&2
472	echo $"          restart|condrestart|try-restart|reload|force-reload" 1>&2
473	echo $"          start-watchdog|stop-watchdog|status-watchdog" 1>&2
474	echo $"          start-powercontrol|stop-powercontrol|status-powercontrol" 1>&2
475	echo $"          stop-all|status-all}" 1>&2
476	RETVAL=2
477}
478
479condrestart ()
480{
481	[ -e ${LOCKFILE} ] && restart
482}
483
484#############################################################################
485# MAIN
486#############################################################################
487case "$1" in
488	start) start ;;
489	stop)  stop ;;
490	restart) restart ;;
491	force-reload) reload ;;
492	reload) reload ;;
493	status)	status ;;
494	status-all) status_all ;;
495	condrestart) condrestart ;;
496	try-restart) condrestart ;;
497	start-watchdog) start_watchdog ;;
498	stop-watchdog) stop_watchdog ;;
499	status-watchdog) status_watchdog ;;
500	start-powercontrol) start_powercontrol ;;
501	stop-powercontrol) stop_powercontrol ;;
502	status-powercontrol) status_powercontrol ;;
503	stop-all) stop_all ;;
504	*) usage ;;
505esac
506
507exit ${RETVAL}
508
509#############################################################################
510# end of file
511#############################################################################
512
513