| #!/bin/bash |
| # |
| # clvmd - Clustered LVM Daemon init script |
| # |
| # chkconfig: - 24 76 |
| # description: Cluster daemon for userland logical volume management tools. |
| # pidfile: @CLVMD_PIDFILE@ |
| # |
| # 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_vgs=${sbindir}/vgs |
| lvm_vgscan=${sbindir}/vgscan |
| lvm_lvs=${sbindir}/lvs |
| |
| 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 $CLVMD_STOP_TIMEOUT ] && CLVMD_STOP_TIMEOUT=10 |
| |
| LOCK_FILE="/var/lock/subsys/$DAEMON" |
| |
| clustered_vgs() { |
| ${lvm_vgs} --noheadings -o vg_name -S 'vg_clustered=1' 2>/dev/null |
| } |
| |
| clustered_active_lvs() { |
| ${lvm_lvs} --noheadings -o lv_name -S 'vg_clustered=1 && lv_active!=""' 2>/dev/null |
| } |
| |
| 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 |