summaryrefslogtreecommitdiffstats
path: root/scripts/clvmd_init_red_hat.in
blob: 41700942a3b6274ddaafa6752e21a25f901edf40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#!/bin/bash
#
# clvmd - Clustered LVM Daemon init script
#
# chkconfig: - 24 76
# description: Cluster daemon for userland logical volume management tools.
#
# For Red-Hat-based distributions such as Fedora, RHEL, CentOS.
#
### BEGIN INIT INFO
# Provides:		clvmd
# Required-Start:	$local_fs@CLVMD_CMANAGERS@
# Required-Stop:	$local_fs@CLVMD_CMANAGERS@
# Short-Description:	This service is Clusterd LVM Daemon.
# Description:		Cluster daemon for userland logical volume management tools.
### END INIT INFO

. /etc/rc.d/init.d/functions

DAEMON=clvmd

exec_prefix=@exec_prefix@
sbindir=@sbindir@

lvm_vgchange=${sbindir}/vgchange
lvm_vgdisplay=${sbindir}/vgdisplay
lvm_vgscan=${sbindir}/vgscan
lvm_lvdisplay=${sbindir}/lvdisplay

CLVMDOPTS="-T30"

[ -f /etc/sysconfig/cluster ] && . /etc/sysconfig/cluster
[ -f /etc/sysconfig/$DAEMON ] && . /etc/sysconfig/$DAEMON

[ -n "$CLVMD_CLUSTER_IFACE" ] && CLVMDOPTS="$CLVMDOPTS -I $CLVMD_CLUSTER_IFACE" 

# allow up to $CLVMD_STOP_TIMEOUT seconds to clvmd to complete exit operations
# default to 10 seconds

[ -z $CLMVD_STOP_TIMEOUT ] && CLVMD_STOP_TIMEOUT=10

LOCK_FILE="/var/lock/subsys/$DAEMON"

# NOTE: replace this with vgs, once display filter per attr is implemented.
clustered_vgs() {
	${lvm_vgdisplay} 2>/dev/null | \
		awk 'BEGIN {RS="VG Name"} {if (/Clustered/) print $1;}'
}

clustered_active_lvs() {
	for i in $(clustered_vgs); do
		${lvm_lvdisplay} $i 2>/dev/null | \
		awk 'BEGIN {RS="LV Name"} {if (/[^N^O^T] available/) print $1;}'
	done
}

rh_status() {
	status $DAEMON
}

rh_status_q() {
	rh_status >/dev/null 2>&1
}

start()
{
	if ! rh_status_q; then
		echo -n "Starting $DAEMON: "
		$DAEMON $CLVMDOPTS || return $?
		echo
	fi

	# Refresh local cache.
	#
	# It's possible that new PVs were added to this, or other VGs
	# while this node was down. So we run vgscan here to avoid
	# any potential "Missing UUID" messages with subsequent
	# LVM commands.

	# The following step would be better and more informative to the user:
	# 'action "Refreshing VG(s) local cache:" ${lvm_vgscan}'
	# but it could show warnings such as:
	# 'clvmd not running on node x-y-z  Unable to obtain global lock.'
	# and the action would be shown as FAILED when in reality it didn't.
	# Ideally vgscan should have a startup mode that would not print
	# unnecessary warnings.

	${lvm_vgscan} > /dev/null 2>&1

	action "Activating VG(s):" ${lvm_vgchange} -aay $LVM_VGS || return $?

	touch $LOCK_FILE

	return 0
}

wait_for_finish()
{
	count=0
	while [ "$count" -le "$CLVMD_STOP_TIMEOUT" ] && \
		 rh_status_q ]; do
		sleep 1
		count=$((count+1))
	done

	! rh_status_q
}

stop()
{
	rh_status_q || return 0

	[ -z "$LVM_VGS" ] && LVM_VGS="$(clustered_vgs)"
	if [ -n "$LVM_VGS" ]; then
		action "Deactivating clustered VG(s):" ${lvm_vgchange} -anl $LVM_VGS || return $?
	fi

	action "Signaling $DAEMON to exit" kill -TERM $(pidofproc $DAEMON) || return $?

	# wait half second before we start the waiting loop or we will show
	# the loop more time than really necessary
	usleep 500000

	# clvmd could take some time to stop
	rh_status_q && action "Waiting for $DAEMON to exit:" wait_for_finish

	if rh_status_q; then
		echo -n "$DAEMON failed to exit"
		failure
		echo
		return 1
	else
		echo -n "$DAEMON terminated"
		success
		echo
	fi

	rm -f $LOCK_FILE

	return 0
}

reload() {
	rh_status_q || exit 7
	action "Reloading $DAEMON configuration: " $DAEMON -R || return $?
}

restart() {
	# if stop fails, restart will return the error and not attempt
	# another start. Even if start is protected by rh_status_q,
	# that would avoid spawning another daemon, it would try to
	# reactivate the VGs.

	# Try to get clvmd to restart itself. This will preserve 
	# exclusive LV locks
	action "Restarting $DAEMON: " $DAEMON -S

	# If that fails then do a normal stop & restart
	if  [ $? != 0 ]; then
	    stop && start
	    return $?
	else
	    touch $LOCK_FILE
	    return 0
	fi
}

[ "$EUID" != "0" ] && {
	echo "clvmd init script can only be executed as root user"
	exit 4
}

# See how we were called.
case "$1" in
  start)
	start
	rtrn=$?
	;;

  stop)
	stop
	rtrn=$?
	;;

  restart|force-reload)
	restart
	rtrn=$?
	;;

  condrestart|try-restart)
	rh_status_q || exit 0
	restart
	rtrn=$? 
	;;

  reload)
	reload
	rtrn=$?
	;;

  status)
	rh_status
	rtrn=$?
	if [ $rtrn = 0 ]; then
		cvgs="$(clustered_vgs)"
		echo Clustered Volume Groups: ${cvgs:-"(none)"}
		clvs="$(clustered_active_lvs)"
		echo Active clustered Logical Volumes: ${clvs:-"(none)"}
	fi
	;;

  *)
	echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
	rtrn=2
	;;
esac

exit $rtrn