]>
Commit | Line | Data |
---|---|---|
e40d44be ZK |
1 | #!/bin/sh |
2 | # | |
3 | # VolumeGroup | |
4 | # | |
5 | # Description: Manages an LVM2 volume group as an HA resource in | |
6 | # an OCF-compliant cluster | |
7 | # | |
8 | # | |
9 | # Authors: Alan Robertson, Lars Marowsky-Bree, Florian Haas, | |
10 | # and others from the Linux-HA project | |
11 | # License: GNU General Public License (GPL) | |
12 | # Copyright: (C) 2002 - 2005 International Business Machines, Inc. | |
13 | # (C) 2010 LINBIT HA-Solutions GmbH | |
14 | # | |
15 | # This code significantly inspired by the LVM resource | |
16 | # in FailSafe by Lars Marowsky-Bree | |
17 | # | |
18 | ####################################################################### | |
19 | # Initialization: | |
20 | ||
21 | : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat} | |
22 | . ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs | |
23 | ||
24 | ####################################################################### | |
25 | ||
26 | ||
27 | usage() { | |
28 | methods=`VolumeGroup_methods` | |
29 | methods=`echo $methods | tr ' ' '|'` | |
30 | cat <<EOF | |
31 | usage: $0 $methods | |
32 | ||
33 | $0 manages an LVM Volume Group (VG) as an HA resource | |
34 | ||
35 | The 'start' operation brings the given volume online | |
36 | The 'stop' operation takes the given volume offline | |
37 | The 'status' operation reports whether the volume is available | |
38 | The 'monitor' operation reports whether the volume seems present | |
39 | The 'validate-all' operation checks whether the OCF parameters are valid | |
40 | The 'methods' operation reports on the methods $0 supports | |
41 | ||
42 | EOF | |
43 | } | |
44 | ||
45 | meta_data() { | |
46 | cat <<EOF | |
47 | <?xml version="1.0"?> | |
48 | <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd"> | |
49 | <resource-agent name="VolumeGroup"> | |
50 | <version>1.0</version> | |
51 | ||
52 | <longdesc lang="en"> | |
53 | Resource script for an LVM Volume Group. | |
54 | </longdesc> | |
55 | <shortdesc lang="en">Controls the availability of an LVM Volume Group</shortdesc> | |
56 | ||
57 | <parameters> | |
58 | <parameter name="volgrpname" unique="0" required="1"> | |
59 | <longdesc lang="en"> | |
60 | The name of volume group. | |
61 | </longdesc> | |
62 | <shortdesc lang="en">Volume group name</shortdesc> | |
63 | <content type="string" default="" /> | |
64 | </parameter> | |
65 | <parameter name="exclusive" unique="0" required="0"> | |
66 | <longdesc lang="en"> | |
67 | If set, the volume group will be activated exclusively. | |
68 | </longdesc> | |
69 | <shortdesc lang="en">Exclusive activation</shortdesc> | |
70 | <content type="boolean" default="false" /> | |
71 | </parameter> | |
72 | </parameters> | |
73 | ||
74 | <actions> | |
75 | <action name="start" timeout="30" /> | |
76 | <action name="stop" timeout="30" /> | |
77 | <action name="status" timeout="30" /> | |
78 | <action name="monitor" depth="0" timeout="30" interval="10" /> | |
79 | <action name="methods" timeout="5" /> | |
80 | <action name="meta-data" timeout="5" /> | |
81 | <action name="validate-all" timeout="5" /> | |
82 | </actions> | |
83 | </resource-agent> | |
84 | EOF | |
85 | } | |
86 | ||
87 | # | |
88 | # methods: What methods/operations do we support? | |
89 | # | |
90 | VolumeGroup_methods() { | |
91 | cat <<EOF | |
92 | start | |
93 | stop | |
94 | status | |
95 | monitor | |
96 | methods | |
97 | validate-all | |
98 | usage | |
99 | EOF | |
100 | } | |
101 | ||
102 | # | |
103 | # Report on LVM volume status. VG may be reported as active | |
104 | # ($OCF_SUCCESS) or inactive ($OCF_NOT_RUNNING) | |
105 | # | |
106 | VolumeGroup_status() { | |
107 | ||
108 | VGOUT=`vgdisplay -v $OCF_RESKEY_volgrpname 2>&1` || exit $OCF_ERR_GENERIC | |
109 | echo "$VGOUT" | grep -i 'Status[ \t]*available' >/dev/null | |
110 | rc=$? | |
111 | ||
112 | if [ $rc -eq 0 ]; then | |
113 | ocf_log debug "LVM Volume Group $OCF_RESKEY_volgrpname is available (started)" | |
114 | else | |
115 | ocf_log debug "LVM Volume Group $OCF_RESKEY_volgrpname is not available (stopped)" | |
116 | return $OCF_NOT_RUNNING | |
117 | fi | |
118 | ||
119 | if echo "$VGOUT" | grep -i 'Access.*read/write' >/dev/null; then | |
120 | ocf_log debug "Volume $OCF_RESKEY_volgrpname is available read/write (running)" | |
121 | else | |
122 | ocf_log debug "Volume $OCF_RESKEY_volgrpname is available read-only (running)" | |
123 | fi | |
124 | ||
125 | return $OCF_SUCCESS | |
126 | } | |
127 | ||
128 | # | |
129 | # Monitor the volume - does it really seem to be working? May report | |
130 | # $OCF_SUCCESS or $OCF_NOT_RUNNING like VolumeGroup_status, plus | |
131 | # $OCF_ERR_GENERIC in case vgck reports an error. | |
132 | # | |
133 | VolumeGroup_monitor() { | |
134 | if ! VolumeGroup_status $OCF_RESKEY_volgrpname; then | |
135 | ocf_log info "LVM Volume Group $OCF_RESKEY_volgrpname is offline" | |
136 | return $OCF_NOT_RUNNING | |
137 | fi | |
138 | ||
139 | ocf_run vgck $OCF_RESKEY_volgrpname || exit $OCF_ERR_GENERIC | |
140 | ||
141 | return $OCF_SUCCESS | |
142 | } | |
143 | ||
144 | # | |
145 | # Activate the volume group, either locally (if $OCF_RESKEY_exclusive | |
146 | # is false or unset), or exclusively (if $OCF_RESKEY_exclusive is | |
147 | # true). | |
148 | # Either returns successfully, or exits with $OCF_ERR_GENERIC. | |
149 | # | |
150 | VolumeGroup_start() { | |
151 | ||
152 | ocf_log info "Activating volume group $OCF_RESKEY_volgrpname" | |
153 | ocf_run vgscan | |
154 | ||
155 | local active_mode | |
156 | active_mode="ly" | |
157 | if ocf_is_true "$OCF_RESKEY_exclusive" ; then | |
158 | active_mode="ey" | |
159 | fi | |
160 | ||
161 | ocf_run vgchange -a $active_mode $OCF_RESKEY_volgrpname || exit $OCF_ERR_GENERIC | |
162 | ||
163 | if ! VolumeGroup_status $OCF_RESKEY_volgrpname; then | |
164 | ocf_log err "LVM: $OCF_RESKEY_volgrpname did not activate correctly" | |
165 | exit $OCF_ERR_GENERIC | |
166 | fi | |
167 | ||
168 | return $OCF_SUCCESS | |
169 | } | |
170 | ||
171 | # | |
172 | # Deactivate the volume group. | |
173 | # Either returns successfully, or exits with $OCF_ERR_GENERIC. | |
174 | # | |
175 | VolumeGroup_stop() { | |
176 | if ! VolumeGroup_status; then | |
177 | ocf_log debug "Volume Group $OCF_RESKEY_volgrpname already stopped" | |
178 | return $OCF_SUCCESS | |
179 | fi | |
180 | ||
181 | ocf_log info "Deactivating volume group $OCF_RESKEY_volgrpname" | |
182 | ocf_run vgchange -a ln $OCF_RESKEY_volgrpname || exit $OCF_ERR_GENERIC | |
183 | ||
184 | if VolumeGroup_status; then | |
185 | ocf_log err "LVM: $OCF_RESKEY_volgrpname did not stop correctly" | |
186 | exit $OCF_ERR_GENERIC | |
187 | fi | |
188 | ||
189 | return $OCF_SUCCESS | |
190 | } | |
191 | ||
192 | # | |
193 | # Check whether the OCF instance parameters are valid. | |
194 | # Either returns successfully, or exits with | |
195 | # $OCF_ERR_CONFIGURED if required parameters are missing; | |
196 | # $OCF_ERR_INSTALLED if required binaries are missing; | |
197 | # $OCF_ERR_GENERIC in case of any other error. | |
198 | # | |
199 | VolumeGroup_validate_all() { | |
200 | ||
201 | if [ -z $OCF_RESKEY_volgrpname ]; then | |
202 | ocf_log err 'Missing required parameter "volgrpname"!' | |
203 | exit $OCF_ERR_CONFIGURED | |
204 | fi | |
205 | ||
206 | check_binary vgchange | |
207 | check_binary vgck | |
208 | check_binary vgdisplay | |
209 | ||
210 | # Run the following tests only if we're not invoked by a probe | |
211 | # operation | |
212 | if ! ocf_is_probe; then | |
213 | # Off-the-shelf tests... | |
214 | vgck "$OCF_RESKEY_volgrpname" >/dev/null 2>&1 | |
215 | if [ $? -ne 0 ]; then | |
216 | ocf_log err "Volume group $OCF_RESKEY_volgrpname does not exist or contains error!" | |
217 | exit $OCF_ERR_GENERIC | |
218 | fi | |
219 | ||
220 | # Double-check | |
221 | vgdisplay -v "$OCF_RESKEY_volgrpname" >/dev/null 2>&1 | |
222 | if [ $? -ne 0 ]; then | |
223 | ocf_log err "Volume group $OCF_RESKEY_volgrpname does not exist or contains error!" | |
224 | exit $OCF_ERR_GENERIC | |
225 | fi | |
226 | fi | |
227 | ||
228 | return $OCF_SUCCESS | |
229 | } | |
230 | ||
231 | # | |
232 | # 'main' starts here... | |
233 | # | |
234 | if [ $# -ne 1 ]; then | |
235 | usage | |
236 | exit $OCF_ERR_ARGS | |
237 | fi | |
238 | ||
239 | case $1 in | |
240 | meta-data) meta_data | |
241 | exit $OCF_SUCCESS;; | |
242 | ||
243 | methods) VolumeGroup_methods | |
244 | exit $OCF_SUCCESS;; | |
245 | ||
246 | usage) usage | |
247 | exit $OCF_SUCCESS;; | |
248 | *) ;; | |
249 | esac | |
250 | ||
251 | # Everything except usage and meta-data must pass the validate test | |
252 | VolumeGroup_validate_all | |
253 | ||
254 | # What kind of method was invoked? | |
255 | case "$1" in | |
256 | start) | |
257 | VolumeGroup_start | |
258 | ;; | |
259 | stop) | |
260 | VolumeGroup_stop | |
261 | ;; | |
262 | status) | |
263 | VolumeGroup_status | |
264 | ;; | |
265 | monitor) | |
266 | VolumeGroup_monitor | |
267 | ;; | |
268 | validate-all) | |
269 | ;; | |
270 | notify|promote|demote|migrate_from|migrate_to) | |
271 | usage | |
272 | exit $OCF_ERR_UNIMPLEMENTED | |
273 | ;; | |
274 | *) usage | |
275 | exit $OCF_ERR_ARGS | |
276 | ;; | |
277 | esac | |
278 | ||
279 | exit $? |