diff --git a/heartbeat/LVM b/heartbeat/LVM index ec1ee7dae..0d05dbd05 100755 --- a/heartbeat/LVM +++ b/heartbeat/LVM @@ -1,672 +1,672 @@ #!/bin/sh # # # LVM # # Description: Manages an LVM volume as an HA resource # # # Author: Alan Robertson # Support: linux-ha@lists.linux-ha.org # License: GNU General Public License (GPL) # Copyright: (C) 2002 - 2005 International Business Machines, Inc. # # This code significantly inspired by the LVM resource # in FailSafe by Lars Marowsky-Bree # # # An example usage in /etc/ha.d/haresources: # node1 10.0.0.170 ServeRAID::1::1 LVM::myvolname # # See usage() function below for more details... # # OCF parameters are as below: # OCF_RESKEY_volgrpname # ####################################################################### # Initialization: : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ####################################################################### usage() { methods=`LVM_methods` methods=`echo $methods | tr ' ' '|'` cat < 1.0 Resource script for LVM. It manages an Linux Volume Manager volume (LVM) as an HA resource. Controls the availability of an LVM Volume Group The name of volume group. Volume group name If set, the volume group will be activated exclusively. This option works one of two ways. If the volume group has the cluster attribute set, then the volume group will be activated exclusively using clvmd across the cluster. If the cluster attribute is not set, the volume group will be activated exclusively using a tag and the volume_list filter. When the tag option is in use, the volume_list in lvm.con must be initialized. This can be as simple as setting 'volume_list = []' depending on your setup. Exclusive activation If "exclusive" is set on a non clustered volume group, this overrides the tag to be used. Exclusive activation tag If set, the volume group will be activated even only partial of the physical volumes available. It helps to set to true, when you are using mirroring logical volumes. Activate VG even with partial PV only EOF } # # methods: What methods/operations do we support? # LVM_methods() { cat < /dev/null 2>&1 if [ $? -ne 0 ]; then return fi ## # Now check to see if the initrd has been updated. # If not, the machine could boot and activate the VG outside # the control of pacemaker ## if [ "$(find /boot -name *.img -newer /etc/lvm/lvm.conf)" = "" ]; then ocf_log warn "LVM: Improper setup detected" ocf_log warn "* initrd image needs to be newer than lvm.conf" # While dangerous if not done the first time, there are many # cases where we don't simply want to fail here. Instead, # keep warning until the user remakes the initrd - or has # it done for them by upgrading the kernel. # # initrd can be updated using this command. # dracut -H -f /boot/initramfs-$(uname -r).img $(uname -r) # fi } ## # does this vg have our tag ## check_tags() { local owner=`vgs -o tags --noheadings $OCF_RESKEY_volgrpname | tr -d ' '` if [ -z "$owner" ]; then # No-one owns this VG yet return 1 fi if [ "$OUR_TAG" = "$owner" ]; then # yep, this is ours return 0 fi # some other tag is set on this vg return 2 } strip_tags() { local i for i in `vgs --noheadings -o tags $OCF_RESKEY_volgrpname | sed s/","/" "/g`; do ocf_log info "Stripping tag, $i" # LVM version 2.02.98 allows changing tags if PARTIAL vgchange --deltag $i $OCF_RESKEY_volgrpname done if [ ! -z `vgs -o tags --noheadings $OCF_RESKEY_volgrpname | tr -d ' '` ]; then ocf_log err "Failed to remove ownership tags from $OCF_RESKEY_volgrpname" return $OCF_ERR_GENERIC fi return $OCF_SUCCESS } set_tags() { check_tags case $? in 0) # we already own it. return $OCF_SUCCESS ;; 2) # other tags are set, strip them before setting if ! strip_tags; then return $OCF_ERR_GENERIC fi ;; *) : ;; esac vgchange --addtag $OUR_TAG $OCF_RESKEY_volgrpname if [ $? -ne 0 ]; then ocf_log err "Failed to add ownership tag to $OCF_RESKEY_volgrpname" return $OCF_ERR_GENERIC fi ocf_log info "New tag \"$OUR_TAG\" added to $OCF_RESKEY_volgrpname" return $OCF_SUCCESS } # # Return LVM status (silently) # LVM_status() { local rc=1 loglevel="debug" # Set the log level of the error message if [ "X${2}" = "X" ]; then loglevel="err" if ocf_is_probe; then loglevel="warn" else if [ ${OP_METHOD} = "stop" ]; then loglevel="info" fi fi fi if [ -d /dev/$1 ]; then test "`cd /dev/$1 && ls`" != "" rc=$? if [ $rc -ne 0 ]; then ocf_log err "VG $1 with no logical volumes is not supported by this RA!" fi fi if [ $rc -ne 0 ]; then ocf_log $loglevel "LVM Volume $1 is not available (stopped)" rc=$OCF_NOT_RUNNING else case $(get_vg_mode) in 1) # exclusive with tagging. # If vg is running, make sure the correct tag is present. Otherwise we # can not guarantee exclusive activation. if ! check_tags; then ocf_log err "WARNING: $OCF_RESKEY_volgrpname is active without the cluster tag, \"$OUR_TAG\"" rc=$OCF_ERR_GENERIC fi # make sure the environment for tags activation is still valid if ! verify_tags_environment; then rc=$OCF_ERR_GENERIC fi # let the user know if their initrd is older than lvm.conf. check_initrd_warning ;; *) : ;; esac fi if [ "X${2}" = "X" ]; then # status call return return $rc fi # Report on LVM volume status to stdout... if [ $rc -eq 0 ]; then echo "Volume $1 is available (running)" else echo "Volume $1 is not available (stopped)" fi return $rc } get_activate_options() { local options="-a" case $(get_vg_mode) in 0) options="${options}ly";; 1) options="${options}y --config activation{volume_list=[\"@${OUR_TAG}\"]}";; 2) options="${options}ey";; esac if ocf_is_true "$OCF_RESKEY_partial_activation" ; then options="${options} --partial" fi # for clones (clustered volume groups), we'll also have to force # monitoring, even if disabled in lvm.conf. if ocf_is_clone; then options="$options --monitor y" fi echo $options } ## # Attempt to deactivate vg cluster wide and then start the vg exclusively ## retry_exclusive_start() { local vgchange_options=$(get_activate_options) # Deactivate each LV in the group one by one cluster wide set -- $(lvs -o name,attr --noheadings $OCF_RESKEY_volgrpname 2> /dev/null) while [ $# -ge 2 ]; do case $2 in ????ao*) # open LVs cannot be deactivated. return $OCF_ERR_GENERIC;; *) if ! lvchange -an $OCF_RESKEY_volgrpname/$1; then ocf_log err "Unable to perform required deactivation of $OCF_RESKEY_volgrpname/$1 before starting" return $OCF_ERR_GENERIC fi ;; esac shift 2 done ocf_run vgchange $vgchange_options $OCF_RESKEY_volgrpname } # # Enable LVM volume # LVM_start() { local vgchange_options=$(get_activate_options) local vg=$1 local clvmd=0 # TODO: This MUST run vgimport as well ocf_log info "Activating volume group $vg" if [ "$LVM_MAJOR" -eq "1" ]; then ocf_run vgscan $vg else ocf_run vgscan fi case $(get_vg_mode) in 2) clvmd=1 ;; 1) if ! set_tags; then return $OCF_ERR_GENERIC fi ;; *) : ;; esac if ! ocf_run vgchange $vgchange_options $vg; then if [ $clvmd -eq 0 ]; then return $OCF_ERR_GENERIC fi # Failure to exclusively activate cluster vg.: # This could be caused by a remotely active LV, Attempt # to disable volume group cluster wide and try again. # Allow for some settling sleep 5 if ! retry_exclusive_start; then return $OCF_ERR_GENERIC fi fi if LVM_status $vg; then : OK Volume $vg activated just fine! return $OCF_SUCCESS else ocf_log err "LVM: $vg did not activate correctly" return $OCF_NOT_RUNNING fi } # # Disable the LVM volume # LVM_stop() { local res=$OCF_ERR_GENERIC local vgchange_options="-aln" local vg=$1 if ! vgs $vg > /dev/null 2>&1; then ocf_log info "Volume group $vg not found" return $OCF_SUCCESS fi ocf_log info "Deactivating volume group $vg" case $(get_vg_mode) in 1) vgchange_options="-an" ;; esac for i in $(seq 10) do ocf_run vgchange $vgchange_options $vg res=$? if LVM_status $vg; then ocf_log err "LVM: $vg did not stop correctly" res=1 fi if [ $res -eq 0 ]; then break fi res=$OCF_ERR_GENERIC ocf_log warn "$vg still Active" ocf_log info "Retry deactivating volume group $vg" sleep 1 which udevadm > /dev/null 2>&1 && udevadm settle --timeout=5 done case $(get_vg_mode) in 1) if [ $res -eq 0 ]; then strip_tags res=$? fi ;; esac return $res } # # Check whether the OCF instance parameters are valid # LVM_validate_all() { check_binary $AWK ## # Off-the-shelf tests... ## VGOUT=`vgck ${VOLUME} 2>&1` if [ $? -ne 0 ]; then ocf_log err "Volume group [$VOLUME] does not exist or contains error! ${VGOUT}" exit $OCF_ERR_GENERIC fi ## # Does the Volume Group exist? ## if [ "$LVM_MAJOR" = "1" ]; then VGOUT=`vgdisplay ${VOLUME} 2>&1` else VGOUT=`vgdisplay -v ${VOLUME} 2>&1` fi if [ $? -ne 0 ]; then ocf_log err "Volume group [$VOLUME] does not exist or contains error! ${VGOUT}" exit $OCF_ERR_GENERIC fi ## # If exclusive activation is not enabled, then # further checking of proper setup is not necessary ## if ! ocf_is_true "$OCF_RESKEY_exclusive"; then return $OCF_SUCCESS; fi ## # Having cloned lvm resources with exclusive vg activation makes no sense at all. ## if ocf_is_clone; then - ocf_log_err "cloned lvm resources can not be activated exclusively" + ocf_log err "cloned lvm resources can not be activated exclusively" exit $OCF_ERR_CONFIGURED fi ## # Make sure the cluster attribute is set and clvmd is up when exclusive # activation is enabled. Otherwise we can't exclusively activate the volume group. ## case $(get_vg_mode) in 1) # exclusive activation using tags if ! verify_tags_environment; then exit $OCF_ERR_GENERIC fi ;; 2) # exclusive activation with clvmd ## # verify is clvmd running ## if ! ps -C clvmd > /dev/null 2>&1; then ocf_log err "$OCF_RESKEY_volgrpname has the cluster attribute set, but 'clvmd' is not running" exit $OCF_ERR_GENERIC fi ;; *) : ;; esac return $OCF_SUCCESS } # # 'main' starts here... # if [ $# -ne 1 ] then usage exit $OCF_ERR_ARGS fi case $1 in meta-data) meta_data exit $OCF_SUCCESS;; methods) LVM_methods exit $?;; usage) usage exit $OCF_SUCCESS;; *) ;; esac if [ -z "$OCF_RESKEY_volgrpname" ] then ocf_log err "You must identify the volume group name!" exit $OCF_ERR_CONFIGURED fi # Get the LVM version number, for this to work we assume(thanks to panjiam): # # LVM1 outputs like this # # # vgchange --version # vgchange: Logical Volume Manager 1.0.3 # Heinz Mauelshagen, Sistina Software 19/02/2002 (IOP 10) # # LVM2 and higher versions output in this format # # # vgchange --version # LVM version: 2.00.15 (2004-04-19) # Library version: 1.00.09-ioctl (2004-03-31) # Driver version: 4.1.0 LVM_VERSION=`vgchange --version 2>&1 | \ $AWK '/Logical Volume Manager/ {print $5"\n"; exit; } /LVM version:/ {printf $3"\n"; exit;}'` rc=$? if ( [ $rc -ne 0 ] || [ -z "$LVM_VERSION" ] ) then ocf_log err "LVM: $1 could not determine LVM version. Try 'vgchange --version' manually and modify $0 ?" exit $OCF_ERR_INSTALLED fi LVM_MAJOR="${LVM_VERSION%%.*}" VOLUME=$OCF_RESKEY_volgrpname OP_METHOD=$1 if [ -n "$OCF_RESKEY_tag" ]; then OUR_TAG=$OCF_RESKEY_tag fi # What kind of method was invoked? case "$1" in start) LVM_validate_all LVM_start $VOLUME exit $?;; stop) LVM_stop $VOLUME exit $?;; status) LVM_status $VOLUME $1 exit $?;; monitor) LVM_status $VOLUME exit $?;; validate-all) LVM_validate_all ;; *) usage exit $OCF_ERR_UNIMPLEMENTED;; esac diff --git a/heartbeat/asterisk b/heartbeat/asterisk index cc78ba1ee..2d9f07600 100755 --- a/heartbeat/asterisk +++ b/heartbeat/asterisk @@ -1,479 +1,479 @@ #!/bin/sh # # # Asterisk # # Description: Manages an Asterisk PBX as an HA resource # # Authors: Martin Gerhard Loschwitz # Florian Haas # # Support: linux-ha@lists.linux-ha.org # License: GNU General Public License (GPL) # # (c) 2011 hastexo Professional Services GmbH # # This resource agent is losely derived from the MySQL resource # agent, which itself is made available to the public under the # following copyright: # # (c) 2002-2005 International Business Machines, Inc. # 2005-2010 Linux-HA contributors # # See usage() function below for more details ... # # OCF instance parameters: # OCF_RESKEY_binary # OCF_RESKEY_canary_binary # OCF_RESKEY_config # OCF_RESKEY_user # OCF_RESKEY_group # OCF_RESKEY_additional_parameters # OCF_RESKEY_realtime # OCF_RESKEY_maxfiles ####################################################################### # Initialization: : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs ####################################################################### # Fill in some defaults if no values are specified HOSTOS=`uname` if [ "X${HOSTOS}" = "XOpenBSD" ]; then OCF_RESKEY_user_default="_asterisk" OCF_RESKEY_group_default="_asterisk" else OCF_RESKEY_user_default="asterisk" OCF_RESKEY_group_default="asterisk" fi OCF_RESKEY_binary_default="asterisk" OCF_RESKEY_canary_binary_default="astcanary" OCF_RESKEY_config_default="/etc/asterisk/asterisk.conf" OCF_RESKEY_additional_parameters_default="-g -vvv" OCF_RESKEY_realtime_default="false" OCF_RESKEY_maxfiles_default="8192" : ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}} : ${OCF_RESKEY_canary_binary=${OCF_RESKEY_canary_binary_default}} : ${OCF_RESKEY_config=${OCF_RESKEY_config_default}} : ${OCF_RESKEY_user=${OCF_RESKEY_user_default}} : ${OCF_RESKEY_group=${OCF_RESKEY_group_default}} : ${OCF_RESKEY_additional_parameters=${OCF_RESKEY_additional_parameters_default}} : ${OCF_RESKEY_realtime=${OCF_RESKEY_realtime_default}} : ${OCF_RESKEY_maxfiles=${OCF_RESKEY_maxfiles_default}} ####################################################################### usage() { cat < 1.0 Resource agent for the Asterisk PBX. May manage an Asterisk PBX telephony system or a clone set that forms an Asterisk distributed device setup. Manages an Asterisk PBX Location of the Asterisk PBX server binary Asterisk PBX server binary Location of the Asterisk PBX Canary server binary Asterisk PBX Canary server binary The Asterisk PBX configuration file Asterisk PBX config User running Asterisk PBX daemon Asterisk PBX user Group running Asterisk PBX daemon (for logfile and directory permissions) Asterisk PBX group Additional parameters which are passed to the Asterisk PBX on startup (e.g. -L <load> or -M <value>). Additional parameters to pass to the Asterisk PBX Determines whether the Asterisk PBX daemon will be run with realtime priority or not. Asterisk PBX realtime priority Determines how many files the Asterisk PBX is allowed to open at a time. Helps to fix the 'Too many open files' error message. Asterisk PBX allowed MAXFILES A SIP URI to check when monitoring. During monitor, the agent will attempt to do a SIP OPTIONS request against this URI. Requires the sipsak utility to be present and executable. If unset, the agent does no SIP URI monitoring. SIP URI to check when monitoring END } ####################################################################### # Convenience functions asterisk_rx() { # if $HOME is set, asterisk -rx writes a .asterisk_history there ( unset HOME ocf_run $OCF_RESKEY_binary -r -s $ASTRUNDIR/asterisk.ctl -x "$1" ) } ####################################################################### # Functions invoked by resource manager actions asterisk_validate() { local rc check_binary $OCF_RESKEY_binary check_binary pgrep if [ -n "$OCF_RESKEY_monitor_sipuri" ]; then check_binary sipsak fi # A config file on shared storage that is not available # during probes is OK. if [ ! -f $OCF_RESKEY_config ]; then if ! ocf_is_probe; then ocf_log err "Config $OCF_RESKEY_config doesn't exist" return $OCF_ERR_INSTALLED fi - ocf_log_warn "Config $OCF_RESKEY_config not available during a probe" + ocf_log warn "Config $OCF_RESKEY_config not available during a probe" fi getent passwd $OCF_RESKEY_user >/dev/null 2>&1 rc=$? if [ $rc -ne 0 ]; then ocf_log err "User $OCF_RESKEY_user doesn't exist" return $OCF_ERR_INSTALLED fi getent group $OCF_RESKEY_group >/dev/null 2>&1 rc=$? if [ $rc -ne 0 ]; then ocf_log err "Group $OCF_RESKEY_group doesn't exist" return $OCF_ERR_INSTALLED fi true } asterisk_status() { local pid local rc if [ ! -f $ASTRUNDIR/asterisk.pid ]; then ocf_log info "Asterisk PBX is not running" return $OCF_NOT_RUNNING fi pid=`cat $ASTRUNDIR/asterisk.pid` ocf_run kill -s 0 $pid rc=$? if [ $rc -eq 0 ]; then if ocf_is_true "$OCF_RESKEY_realtime"; then astcanary_pid=`pgrep -d " " -f "astcanary $ASTRUNDIR/alt.asterisk.canary.tweet.tweet.tweet"` if [ ! "$astcanary_pid" ]; then ocf_log err "Asterisk PBX is running but astcanary is not although it should" return $OCF_ERR_GENERIC fi else return $OCF_SUCCESS fi else ocf_log info "Asterisk PBX not running: removing old PID file" rm -f $ASTRUNDIR/asterisk.pid return $OCF_NOT_RUNNING fi } asterisk_monitor() { local rc asterisk_status rc=$? # If status returned an error, return that immediately if [ $rc -ne $OCF_SUCCESS ]; then return $rc fi # Check whether connecting to asterisk is possible asterisk_rx 'core show channels count' rc=$? if [ $rc -ne 0 ]; then ocf_log err "Failed to connect to the Asterisk PBX" return $OCF_ERR_GENERIC fi # Optionally check the monitor URI with sipsak # The return values: # 0 means that a 200 was received. # 1 means something else then 1xx or 2xx was received. # 2 will be returned on local errors like non resolvable names # or wrong options combination. # 3 will be returned on remote errors like socket errors # (e.g. icmp error), redirects without a contact header or # simply no answer (timeout). # This can also happen if sipsak is run too early after asterisk # start. if [ -n "$OCF_RESKEY_monitor_sipuri" ]; then ocf_run sipsak -s "$OCF_RESKEY_monitor_sipuri" rc=$? case "$rc" in 1|2) return $OCF_ERR_GENERIC;; 3) return $OCF_NOT_RUNNING;; esac fi ocf_log debug "Asterisk PBX monitor succeeded" return $OCF_SUCCESS } asterisk_start() { local asterisk_extra_params local dir local rc asterisk_status rc=$? if [ $rc -eq $OCF_SUCCESS ]; then ocf_log info "Asterisk PBX already running" return $OCF_SUCCESS fi # If Asterisk is not already running, make sure there is no # old astcanary instance when the new asterisk starts. To # achieve this, kill old astcanary instances belonging to # this $ASTRUNDIR. # Find out PIDs of running astcanaries astcanary_pid=`pgrep -d " " -f "astcanary $ASTRUNDIR/alt.asterisk.canary.tweet.tweet.tweet"` # If there are astcanaries running that belong to $ASTRUNDIR, # kill them. if [ "$astcanary_pid" ]; then for i in $astcanary_pid; do ocf_run kill -s KILL $astcanary_pid; done fi for dir in $ASTRUNDIR $ASTLOGDIR $ASTLOGDIR/cdr-csv $ASTLOGDIR/cdr-custom; do if [ ! -d "$dir" ]; then ocf_run install -d -o $OCF_RESKEY_user -g $OCF_RESKEY_group $dir \ || exit $OCF_ERR_GENERIC fi # Regardless of whether we just created the directory or it # already existed, check whether it is writable by the configured # user if ! su -s /bin/sh - $OCF_RESKEY_user -c "test -w $dir"; then ocf_log err "Directory $dir is not writable by $OCF_RESKEY_user" exit $OCF_ERR_PERM fi done # set MAXFILES ulimit -n $OCF_RESKEY_maxfiles # Determine whether Asterisk PBX is supposed to run in Realtime mode # or not and make asterisk daemonize automatically if ocf_is_true "$OCF_RESKEY_realtime"; then asterisk_extra_params="-F -p" else asterisk_extra_params="-F" fi ocf_run ${OCF_RESKEY_binary} -G $OCF_RESKEY_group -U $OCF_RESKEY_user \ -C $OCF_RESKEY_config \ $OCF_RESKEY_additional_parameters \ $asterisk_extra_params rc=$? if [ $rc -ne 0 ]; then ocf_log err "Asterisk PBX start command failed: $rc" exit $OCF_ERR_GENERIC fi # Spin waiting for the server to come up. # Let the CRM/LRM time us out if required while true; do asterisk_monitor rc=$? [ $rc -eq $OCF_SUCCESS ] && break if [ $rc -ne $OCF_NOT_RUNNING ]; then ocf_log err "Asterisk PBX start failed" exit $OCF_ERR_GENERIC fi sleep 2 done ocf_log info "Asterisk PBX started" return $OCF_SUCCESS } asterisk_stop() { local pid local astcanary_pid local rc asterisk_status rc=$? if [ $rc -eq $OCF_NOT_RUNNING ]; then ocf_log info "Asterisk PBX already stopped" return $OCF_SUCCESS fi pid=`cat $ASTRUNDIR/asterisk.pid` ocf_run kill -s TERM $pid rc=$? if [ $rc -ne 0 ]; then ocf_log err "Asterisk PBX couldn't be stopped" exit $OCF_ERR_GENERIC fi # stop waiting shutdown_timeout=15 if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then shutdown_timeout=$((($OCF_RESKEY_CRM_meta_timeout/1000)-5)) fi count=0 while [ $count -lt $shutdown_timeout ]; do asterisk_status rc=$? if [ $rc -eq $OCF_NOT_RUNNING ]; then break fi count=`expr $count + 1` sleep 1 ocf_log debug "Asterisk PBX still hasn't stopped yet. Waiting ..." done asterisk_status rc=$? if [ $rc -ne $OCF_NOT_RUNNING ]; then # SIGTERM didn't help either, try SIGKILL ocf_log info "Asterisk PBX failed to stop after ${shutdown_timeout}s using SIGTERM. Trying SIGKILL ..." ocf_run kill -s KILL $pid fi # After killing asterisk, stop astcanary if ocf_is_true "$OCF_RESKEY_realtime"; then astcanary_pid=`pgrep -d " " -f "astcanary $ASTRUNDIR/alt.asterisk.canary.tweet.tweet.tweet"` if [ "$astcanary_pid" ]; then for i in $astcanary_pid; do ocf_run kill -s KILL $astcanary_pid; done fi fi ocf_log info "Asterisk PBX stopped" return $OCF_SUCCESS } ####################################################################### case "$1" in meta-data) meta_data exit $OCF_SUCCESS;; usage|help) usage exit $OCF_SUCCESS;; esac # Anything except meta-data and help must pass validation asterisk_validate || exit $? # Now that validate has passed and we can be sure to be able to read # the config file, set convenience variables ASTRUNDIR=`grep astrundir $OCF_RESKEY_config | awk '/^astrundir/ {print $3}'` ASTLOGDIR=`grep astlogdir $OCF_RESKEY_config | awk '/^astlogdir/ {print $3}'` # What kind of method was invoked? case "$1" in start) asterisk_start;; stop) asterisk_stop;; status) asterisk_status;; monitor) asterisk_monitor;; validate-all) ;; *) usage exit $OCF_ERR_UNIMPLEMENTED;; esac