3 # OCF resource agent for mapping and unmapping
4 # RADOS Block Devices (RBDs)
6 # License: GNU Lesser General Public License (LGPL) 2.1
7 # (c) 2012 Florian Haas, hastexo
11 : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
12 . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
14 # Convenience variables
15 # When sysconfdir isn't passed in as a configure flag,
16 # it's defined in terms of prefix
20 OCF_RESKEY_pool_default="rbd"
21 OCF_RESKEY_cephconf_default="@sysconfdir@/@PACKAGE_TARNAME@/@PACKAGE_TARNAME@.conf"
22 : ${OCF_RESKEY_pool=${OCF_RESKEY_pool_default}}
23 : ${OCF_RESKEY_cephconf=${OCF_RESKEY_cephconf_default}}
28 <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
29 <resource-agent name="rbd" version="0.1">
30 <version>0.1</version>
32 Manages RADOS Block Devices (RBDs) as a highly available
33 resource. Maps and unmaps RBDs as needed.
35 <shortdesc lang="en">Maps and unmaps RADOS Block Devices</shortdesc>
37 <parameter name="name" unique="0" required="1">
39 Name of the RBD device.
41 <shortdesc lang="en">RBD device name</shortdesc>
42 <content type="string"/>
44 <parameter name="pool" unique="0" required="0">
46 Name of the RADOS pool where the RBD has been created
48 <shortdesc lang="en">RADOS pool name</shortdesc>
49 <content type="string" default="${OCF_RESKEY_pool_default}"/>
51 <parameter name="snap" unique="0" required="0">
53 Name of the device snapshot to map.
55 <shortdesc lang="en">Snapshot name</shortdesc>
56 <content type="string"/>
58 <parameter name="cephconf" unique="0" required="0">
60 Location of the Ceph configuration file
62 <shortdesc lang="en">Ceph configuration file</shortdesc>
63 <content type="string" default="${OCF_RESKEY_cephconf_default}"/>
65 <parameter name="mon" unique="0" required="0">
67 Address (or comma-separated list of addresses) of
68 monitor servers to connect to. Overrides values from
71 <shortdesc lang="en">Monitor address(es)</shortdesc>
72 <content type="string"/>
74 <parameter name="user" unique="0" required="0">
76 Username to use when mapping the device. Required
77 if Ceph authentication is enabled on the monitor.
79 <shortdesc lang="en">Authentication username</shortdesc>
80 <content type="string"/>
82 <parameter name="secret" unique="0" required="0">
84 File containing an authentication secret. Required
85 if Ceph authentication is enabled on the monitor.
87 <shortdesc lang="en">Authentication secret file</shortdesc>
88 <content type="string"/>
92 <action name="start" timeout="20" />
93 <action name="stop" timeout="20" />
94 <action name="monitor" timeout="20"
95 interval="10" depth="0" />
96 <action name="meta-data" timeout="5" />
97 <action name="validate-all" timeout="20" />
105 usage: $0 {start|stop|status|monitor|validate-all|meta-data}
107 Expects to have a fully populated OCF RA-compliant environment set.
111 # rbd command wrapper: builds an option string for invoking RBD based
112 # on resource parameters, and invokes rbd through ocf_run.
116 if [ -n "${OCF_RESKEY_cephconf}" ]; then
117 rbd_options="$rbd_options -c ${OCF_RESKEY_cephconf}"
119 if [ -n "${OCF_RESKEY_mon}" ]; then
120 rbd_options="$rbd_options -m ${OCF_RESKEY_mon}"
123 ocf_run rbd $rbd_options $@
126 # Convenience function that uses "rbd showmapped" to retrieve the
127 # mapped device name from the pool, RBD name, and snapshot.
131 # Example output from "rbd showmapped" (tab separated):
132 # id pool image snap device
133 # 0 rbd test - /dev/rbd0
135 # Build the sed pattern, substituting "-" for the snapshot name if
137 sedpat="[0-9]\+[ \t]\+${OCF_RESKEY_pool}[ \t]\+${OCF_RESKEY_name}[ \t]\+${OCF_RESKEY_snap:--}[ \t]\+\(/dev/rbd[0-9]\+\).*"
139 # Run rbd showmapped, filter out the header line, then try to
140 # extract the device name
141 rbd showmapped | tail -n +2 | sed -n -e "s,$sedpat,\1,p"
145 # Test for configuration errors first
146 if [ -z "$OCF_RESKEY_name" ]; then
147 ocf_log err 'Required parameter "name" is unset!'
148 exit $OCF_ERR_CONFIGURED
151 # Test for required binaries
161 if ! [ -d /sys/bus/rbd ]; then
162 ocf_log debug "rbd module is not loaded"
163 return $OCF_NOT_RUNNING
166 rbd_dev=`find_rbd_dev`
168 if [ -z "$rbd_dev" ]; then
169 ocf_log debug "RBD device is unmapped"
171 elif [ -b "$rbd_dev" ]; then
172 ocf_log debug "RBD device is mapped to $rbd_dev"
175 # Device is listed, but the corresponding path is not a block
177 ocf_log err "$rbd_dev is not a block device!"
185 local rbd_map_options
188 # if resource is already running, bail out early
190 ocf_log info "Resource is already running"
194 # actually start up the resource here (make sure to immediately
195 # exit with an $OCF_ERR_ error code if anything goes seriously
198 if [ ! -d /sys/bus/rbd ]; then
199 ocf_run modprobe -v rbd || exit $OCF_ERR_INSTALLED
202 if [ -n "${OCF_RESKEY_user}" ]; then
203 rbd_map_options="--id ${OCF_RESKEY_user}"
205 if [ -n "${OCF_RESKEY_secret}" ]; then
206 rbd_map_options="$rbd_map_options --keyfile ${OCF_RESKEY_secret}"
209 rbd_name="${OCF_RESKEY_pool}/${OCF_RESKEY_name}"
210 if [ -n "${OCF_RESKEY_snap}" ]; then
211 rbd_name="$rbd_name@${OCF_RESKEY_snap}"
214 do_rbd map $rbd_name $rbd_map_options || exit $OCF_ERR_GENERIC
216 # After the resource has been started, check whether it started up
217 # correctly. If the resource starts asynchronously, the agent may
218 # spin on the monitor function here -- if the resource does not
219 # start up within the defined timeout, the cluster manager will
220 # consider the start action failed
221 while ! rbd_monitor; do
222 ocf_log debug "Resource has not started yet, waiting"
226 # only return $OCF_SUCCESS if _everything_ succeeded as expected
238 # Currently running. Normal, expected behavior.
239 ocf_log debug "Resource is currently running"
242 # Currently not running. Nothing to do.
243 ocf_log info "Resource is already stopped"
248 # actually shut down the resource here (make sure to immediately
249 # exit with an $OCF_ERR_ error code if anything goes seriously
251 rbd_dev=`find_rbd_dev`
252 do_rbd unmap $rbd_dev || exit $OCF_ERR_GENERIC
254 # After the resource has been stopped, check whether it shut down
255 # correctly. If the resource stops asynchronously, the agent may
256 # spin on the monitor function here -- if the resource does not
257 # shut down within the defined timeout, the cluster manager will
258 # consider the stop action failed
259 while rbd_monitor; do
260 ocf_log debug "Resource has not stopped yet, waiting"
264 # only return $OCF_SUCCESS if _everything_ succeeded as expected
269 # Make sure meta-data and usage always succeed
270 case $__OCF_ACTION in
271 meta-data) rbd_meta_data
274 usage|help) rbd_usage
279 # Anything other than meta-data and usage must pass validation
280 rbd_validate_all || exit $?
282 # Translate each action into the appropriate function call
283 case $__OCF_ACTION in
286 status|monitor) rbd_monitor;;
289 exit $OCF_ERR_UNIMPLEMENTED
294 # The resource agent may optionally log a debug message
295 ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION returned $rc"