#!/bin/bash # # lustre This shell script takes care of starting and stopping # the lustre services. # # chkconfig: - 60 20 # description: Part of the lustre file system. # probe: true # config: /etc/sysconfig/lustre PATH=/sbin:/usr/sbin:/bin:/usr/bin # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. if [ ! -f /etc/sysconfig/network ]; then exit 0 fi . /etc/sysconfig/network LDEV=${LDEV:-"/usr/sbin/ldev"} ZPOOL_LAYOUT=/usr/bin/zpool_layout UDEVADM=${UDEVADM:-/sbin/udevadm} # Check that networking is up. [ "${NETWORKING}" = "no" ] && exit 0 # Check for and source configuration file otherwise set defaults [ -f /etc/sysconfig/lustre ] && . /etc/sysconfig/lustre FSCK_ARGS=${FSCK_ARGS:-""} MOUNT_OPTIONS=${MOUNT_OPTIONS:-""} LOCAL_SRV=${LOCAL_SRV:-"`$LDEV -l 2>/dev/null`"} FOREIGN_SRV=${FOREIGN_SRV:-"`$LDEV -f 2>/dev/null`"} REQUIRE_MMP_FEATURE=${REQUIRE_MMP_FEATURE:-${FOREIGN_SRV:+"yes"}} LOCAL_MOUNT_DIR=${LOCAL_MOUNT_DIR:-"/mnt/lustre/local"} FOREIGN_MOUNT_DIR=${FOREIGN_MOUNT_DIR:-"/mnt/lustre/foreign"} SETUP_DEVICES=${SETUP_DEVICES:-""} ZPOOL_LAYOUT_BUSES=${ZPOOL_LAYOUT_BUSES:-""} ZPOOL_LAYOUT_PORTS=${ZPOOL_LAYOUT_PORTS:-""} ZPOOL_LAYOUT_MAP=${ZPOOL_LAYOUT_MAP:-""} MOUNT_DELAY=${MOUNT_DELAY:-2} LOAD_ZFS=${LOAD_ZFS:-""} if [ -z "$TUNE2FS" ] ; then TUNE2FS=`which tunefs.ldiskfs 2>/dev/null` if [ -z "$TUNE2FS" ] ; then TUNE2FS=`which tune2fs 2>/dev/null` fi fi if [ -z "$PFSCK" ] ; then PFSCK=`which pfsck.ldiskfs 2>/dev/null` if [ -z "$PFSCK" ] ; then PFSCK=`which fsck 2>/dev/null` fi fi shopt -s nullglob start_zfs_services () { if [ -n "$ZPOOL_LAYOUT_BUSES" -a -n "$ZPOOL_LAYOUT_PORTS" ] ; then MAP_ARG=${ZPOOL_LAYOUT_MAP:+"-m $ZPOOL_LAYOUT_MAP"} $ZPOOL_LAYOUT -t -b "$ZPOOL_LAYOUT_BUSES" \ -p "$ZPOOL_LAYOUT_PORTS" $MAP_ARG fi if [ "$LOAD_ZFS" = "yes" ] && ! modprobe zfs ; then echo "Failed to load zfs module. Aborting." exit 1 fi } stop_devices () { local labels=$* local label devtype for label in $labels; do devtype=`$LDEV -t $label` if [ "$devtype" = "zfs" ] ; then export_zpool $label elif [ "$devtype" = "md" ] ; then dev=`label_to_device $label` journal=`$LDEV -j $label` stop_md_device $dev stop_md_device $journal fi done } import_zpool () { local result=1 local label=$1 local pool=`$LDEV -z $label` local args="-N $ZPOOL_IMPORT_ARGS" local cache=`$LDEV -r $label` # -c is incompatible with -d if [ -n "$cache" ] ; then args="$args -c $cache" elif [ -n "$ZPOOL_IMPORT_DIR" ] ; then args="$args -d $ZPOOL_IMPORT_DIR" fi if zpool status $pool >/dev/null 2>&1 ; then result=0 elif [ -n "$pool" ] ; then zpool import $pool $args 2>/dev/null result=$? fi if [ $result -ne 0 ] ; then echo "Unexpected return code from import of pool $pool: $result" fi return $result } export_zpool () { local label=$1 local pool=`$LDEV -z $label` zpool export $pool 2>/dev/null } # Trigger udev and wait for it to settle. udev_trigger() { if [ -x ${UDEVADM} ]; then ${UDEVADM} trigger --action=change --subsystem-match=block ${UDEVADM} settle else /sbin/udevtrigger /sbin/udevsettle fi } # Usage: run_preexec_check [ start | restart | condrestart ] # The single parameter will be passed to the PREEXEC_SCRIPT run_preexec_check () { if [ -n "$PREEXEC_CHECK" ] && ! $PREEXEC_CHECK ; then echo "Pre-exec check \"$PREEXEC_CHECK\" failed. Aborting." exit 1 fi if [ -n "$PREEXEC_SCRIPT" ] && ! "$PREEXEC_SCRIPT" "$1" ; then echo "Pre-exec script \"$PREEXEC_SCRIPT\" failed. Aborting." exit 1 fi } # Usage: run_postexec_check [ start | restart | condrestart ] # The single parameter will be passed to the PREEXEC_SCRIPT run_postexec_check () { if [ -n "$POSTEXEC_CHECK" ] && ! $POSTEXEC_CHECK ; then echo "Post-exec check \"$POSTEXEC_CHECK\" failed. Aborting." exit 1 fi if [ -n "$POSTEXEC_SCRIPT" ] && ! "$POSTEXEC_SCRIPT" "$1" ; then echo "Post-exec script \"$POSTEXEC_SCRIPT\" failed. Aborting." exit 1 fi } # Usage: adjust_scsi_timeout adjust_scsi_timeout () { local dev=$1 if [ -n "$SCSI_DEVICE_TIMEOUT" ]; then # make sure that it is actually a SCSI (sd) device local name=`basename $dev` local proc=/sys/block/${name}/device/timeout local driver=`readlink /sys/block/${name}/device/driver` if [ -n "$driver" ] && [ "`basename $driver`" == "sd" ]; then if ! echo $SCSI_DEVICE_TIMEOUT >$proc; then echo "FAILED: could not adjust ${dev} timeout" return 1 fi fi fi return 0 } # Usage: fsck_test [ ... ] # Checks all devices in parallel if FSCK_ARGS is set. fsck_test () { local devices="$*" # Filter out non-absolute paths, which are probably ZFS datasets devices=`echo $devices |xargs -n 1|grep '^/'|xargs` if [ -n "${FSCK_ARGS}" -a -n "$devices" ]; then if [ -x $PFSCK ] ; then echo "$PFSCK $devices -- ${FSCK_ARGS}" $PFSCK $devices -- ${FSCK_ARGS} if [ $? -ne 0 -a $? -ne 1 ] ; then echo "FAILED: $PFSCK -- ${FSCK_ARGS}: $?" return 1 fi else echo "$PFSCK not found" return 1 fi fi return 0 } # Usage: test_feature_flag test_feature_flag() { local dev=$1 local flag=$2 local result=1 local feature for feature in `$TUNE2FS -l $dev 2>/dev/null \ | grep features: | sed -e 's/^.*: //'`; do if [ "$feature" == "$flag" ]; then result=0 break fi done return $result } # Usage: mmp_test # Returns 0 if it is set or not required, 1 if unset and required or error. mmp_test () { local dev=$1 local result=0 if [ "$REQUIRE_MMP_FEATURE" == "yes" ]; then if [ -x $TUNE2FS ]; then if ! test_feature_flag $dev "mmp"; then echo "mmp feature flag is not set on $dev" result=1 fi else echo "$TUNE2FS not found" result=1 fi fi return $result } # Usage: label_to_mountpt