#!/bin/bash # # chkconfig: - 70 08 # description: Loads and unloads the drbd module # # Copyright 2001-2010 LINBIT # # Philipp Reisner, Lars Ellenberg # ### BEGIN INIT INFO # Provides: drbd # Required-Start: $local_fs $network $syslog # Required-Stop: $local_fs $network $syslog # Should-Start: sshd multipathd # Should-Stop: sshd multipathd # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # X-Start-Before: heartbeat corosync # X-Stop-After: heartbeat corosync # Short-Description: Control drbd resources. ### END INIT INFO DEFAULTFILE="/etc/default/drbd" DRBDADM="/sbin/drbdadm" DRBDSETUP="/sbin/drbdsetup" PROC_DRBD="/proc/drbd" MODPROBE="/sbin/modprobe" RMMOD="/sbin/rmmod" UDEV_TIMEOUT=10 ADD_MOD_PARAM="" if [ -f $DEFAULTFILE ]; then . $DEFAULTFILE fi test -f $DRBDADM || exit 5 # we only use these two functions, define fallback versions of them ... log_daemon_msg() { echo -n "${1:-}: ${2:-}"; } log_end_msg() { echo "."; } # ... and let the lsb override them, if it thinks it knows better. if [ -f /lib/lsb/init-functions ]; then . /lib/lsb/init-functions fi function assure_module_is_loaded { [ -e "$PROC_DRBD" ] && return $MODPROBE -s drbd `$DRBDADM sh-mod-parms` $ADD_MOD_PARAM || { echo "Can not load the drbd module."$'\n'; exit 20 } # tell klogd to reload module symbol information ... [ -e /var/run/klogd.pid ] && [ -x /sbin/klogd ] && /sbin/klogd -i } function adjust_with_progress { IFS_O=$IFS NEWLINE=' ' IFS=$NEWLINE local res out COMMANDS=`$DRBDADM -d -n res adjust all` || exit 20 echo -n "[ " for CMD in $COMMANDS; do case "$CMD" in res=*) eval "$CMD";; *\ disk\ *) # Check for offline resize. If using internal meta data, # we may need to move it first to its expected location. out=$($DRBDADM check-resize "$res" 2>&1) [[ -z $out ]] || printf "\n%s\n%s\n" "$res" "$out" echo -n "d($res) " ;; *\ syncer\ *) echo -n "s($res) " ;; *\ net\ *) echo -n "n($res) " ;; *) echo ".. " ;; esac if ! eval "$CMD"; then echo -e "\n[$res] cmd $CMD failed - continuing!\n " fi done echo -n "]" IFS=$IFS_O } drbd_pretty_status() { local proc_drbd=$1 # add resource names if ! type column &> /dev/null || ! type paste &> /dev/null || ! type join &> /dev/null || ! type sed &> /dev/null || ! type tr &> /dev/null then cat "$proc_drbd" return fi sed -e '2q' < "$proc_drbd" sed_script=$( i=0; _sh_status_process() { let i++ ; stacked=${_stacked_on:+"^^${_stacked_on_minor:-${_stacked_on//[!a-zA-Z0-9_ -]/_}}"} printf "s|^ *%u:|%6u\t&%s%s|\n" \ $_minor $i \ "${_res_name//[!a-zA-Z0-9_ -]/_}" "$stacked" }; eval "$(drbdadm sh-status)" ) p() { sed -e "1,2d" \ -e "$sed_script" \ -e '/^ *[0-9]\+: cs:Unconfigured/d;' \ -e 's/^\(.* cs:.*[^ ]\) \([rs]...\)$/\1 - \2/g' \ -e 's/^\(.* \)cs:\([^ ]* \)st:\([^ ]* \)ds:\([^ ]*\)/\1\2\3\4/' \ -e 's/^\(.* \)cs:\([^ ]* \)ro:\([^ ]* \)ds:\([^ ]*\)/\1\2\3\4/' \ -e 's/^\(.* \)cs:\([^ ]*\)$/\1\2/' \ -e 's/^ *[0-9]\+:/ x &??not-found??/;' \ -e '/^$/d;/ns:.*nr:.*dw:/d;/resync:/d;/act_log:/d;' \ -e 's/^\(.\[.*\)\(sync.ed:\)/... ... \2/;/^.finish:/d;' \ -e 's/^\(.[0-9 %]*oos:\)/... ... \1/' \ < "$proc_drbd" | tr -s '\t ' ' ' } m() { join -1 2 -2 1 -o 1.1,2.2,2.3 \ <( ( drbdadm sh-dev all ; drbdadm -S sh-dev all ) | cat -n | sort -k2,2) \ <(sort < /proc/mounts ) | sort -n | tr -s '\t ' ' ' | sed -e 's/^ *//' } # echo "=== p ===" # p # echo "=== m ===" # m # echo "=========" # join -a1 <(p|sort) <(m|sort) # echo "=========" ( echo m:res cs ro ds p mounted fstype join -a1 <(p|sort) <(m|sort) | cut -d' ' -f2-6,8- | sort -k1,1n -k2,2 ) | column -t } case "$1" in start) # Just in case drbdadm want to display any errors in the configuration # file, or we need to ask the user about registering this installation # at http://usage.drbd.org, we call drbdadm here without any IO # redirection. $DRBDADM sh-nop log_daemon_msg "Starting DRBD resources" assure_module_is_loaded adjust_with_progress # make sure udev has time to create the device files for RESOURCE in `$DRBDADM sh-resources`; do for DEVICE in `$DRBDADM sh-dev $RESOURCE`; do UDEV_TIMEOUT_LOCAL=$UDEV_TIMEOUT while [ ! -e $DEVICE ] && [ $UDEV_TIMEOUT_LOCAL -gt 0 ] ; do sleep 1 UDEV_TIMEOUT_LOCAL=$(( $UDEV_TIMEOUT_LOCAL-1 )) done done done [ -d /var/lock/subsys ] && touch /var/lock/subsys/drbd # for RedHat $DRBDADM wait-con-int # User interruptible version of wait-connect all $DRBDADM sh-b-pri all # Become primary if configured log_end_msg 0 ;; stop) $DRBDADM sh-nop log_daemon_msg "Stopping all DRBD resources" if [ -e $PROC_DRBD ] ; then # bypass drbdadm and drbd config file and everything, # to avoid leaving devices around that are not referenced by # the current config file, or in case the current config file # does not parse for some reason. for d in /dev/drbd* ; do [ -L "$d" ] && continue [ -b "$d" ] || continue M=$(umount "$d" 2>&1) case $M in *" not mounted") :;; *) echo "$M" >&2 ;; esac $DRBDSETUP "$d" down done $RMMOD drbd fi [ -f /var/lock/subsys/drbd ] && rm /var/lock/subsys/drbd log_end_msg 0 ;; status) # NEEDS to be heartbeat friendly... # so: put some "OK" in the output. if [ -e $PROC_DRBD ]; then echo "drbd driver loaded OK; device status:" drbd_pretty_status $PROC_DRBD 2>/dev/null exit 0 else echo >&2 "drbd not loaded" exit 3 fi ;; reload) $DRBDADM sh-nop log_daemon_msg "Reloading DRBD configuration" $DRBDADM adjust all log_end_msg 0 ;; restart|force-reload) $DRBDADM sh-nop log_daemon_msg "Restarting all DRBD resources" $DRBDADM down all $RMMOD drbd assure_module_is_loaded $DRBDADM up all log_end_msg 0 ;; *) echo "Usage: /etc/init.d/drbd {start|stop|status|reload|restart|force-reload}" exit 1 ;; esac exit 0