| #!/usr/bin/env bash |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| |
| ##################################################################################### |
| # |
| # Given a lun # and a WWID for a volume provisioned externally, find the volume |
| # through the SCSI bus and make sure its visable via multipath |
| # |
| ##################################################################################### |
| |
| |
| LUN=${1:?"LUN required"} |
| WWID=${2:?"WWID required"} |
| |
| WWID=$(echo $WWID | tr '[:upper:]' '[:lower:]') |
| |
| systemctl is-active multipathd || systemctl restart multipathd || { |
| echo "$(date): Multipathd is NOT running and cannot be started. This must be corrected before this host can access this storage volume." |
| logger -t "CS_SCSI_VOL_FIND" "${WWID} cannot be mapped to this host because multipathd is not currently running and cannot be started" |
| exit 1 |
| } |
| |
| echo "$(date): Looking for ${WWID} on lun ${LUN}" |
| |
| # get vendor OUI. we will only delete a device on the designated lun if it matches the |
| # incoming WWN OUI value. This is because multiple storage arrays may be mapped to the |
| # host on different fiber channel hosts with the same LUN |
| INCOMING_OUI=$(echo ${WWID} | cut -c2-7) |
| echo "$(date): Incoming OUI: ${INCOMING_OUI}" |
| |
| # first we need to check if any stray references are left from a previous use of this lun |
| for fchost in $(ls /sys/class/fc_host | sed -e 's/host//g'); do |
| lingering_devs=$(lsscsi -w "${fchost}:*:*:${LUN}" | grep /dev | awk '{if (NF > 6) { printf("%s:%s ", $NF, $(NF-1));} }' | sed -e 's/0x/3/g') |
| |
| if [ ! -z "${lingering_devs}" ]; then |
| for dev in ${lingering_devs}; do |
| LSSCSI_WWID=$(echo $dev | awk -F: '{print $2}' | sed -e 's/0x/3/g') |
| FOUND_OUI=$(echo ${LSSCSI_WWID} | cut -c3-8) |
| if [ "${INCOMING_OUI}" != "${FOUND_OUI}" ]; then |
| continue; |
| fi |
| dev=$(echo $dev | awk -F: '{ print $1}') |
| logger -t "CS_SCSI_VOL_FIND" "${WWID} processing identified a lingering device ${dev} from previous lun use, attempting to clean up" |
| MP_WWID=$(multipath -l ${dev} | head -1 | awk '{print $1}') |
| MP_WWID=${MP_WWID:1} # strip first character (3) off |
| # don't do this if the WWID passed in matches the WWID from multipath |
| if [ ! -z "${MP_WWID}" ] && [ "${MP_WWID}" != "${WWID}" ]; then |
| # run full removal again so all devices and multimap are cleared |
| $(dirname $0)/disconnectVolume.sh ${MP_WWID} |
| # we don't have a multimap but we may still have some stranded devices to clean up |
| elif [ "${LSSCSI_WWID}" != "${WWID}" ]; then |
| echo "1" > /sys/block/$(echo ${dev} | awk -F'/' '{print $NF}')/device/delete |
| fi |
| done |
| sleep 3 |
| fi |
| done |
| |
| logger -t "CS_SCSI_VOL_FIND" "${WWID} awaiting disk path at /dev/mapper/3${WWID}" |
| |
| # wait for multipath to map the new lun to the WWID |
| echo "$(date): Waiting for multipath entry to show up for the WWID" |
| while true; do |
| ls /dev/mapper/3${WWID} >/dev/null 2>&1 |
| if [ $? == 0 ]; then |
| break |
| fi |
| |
| logger -t "CS_SCSI_VOL_FIND" "${WWID} not available yet, triggering scan" |
| |
| # instruct bus to scan for new lun |
| for fchost in $(ls /sys/class/fc_host); do |
| echo " --> Scanning ${fchost}" |
| echo "- - ${LUN}" > /sys/class/scsi_host/${fchost}/scan |
| done |
| |
| multipath -v2 2>/dev/null |
| |
| ls /dev/mapper/3${WWID} >/dev/null 2>&1 |
| if [ $? == 0 ]; then |
| break |
| fi |
| |
| sleep 5 |
| done |
| |
| echo "$(date): Doing a recan to make sure we have proper current size locally" |
| for device in $(multipath -ll 3${WWID} | egrep '^ ' | awk '{print $2}'); do |
| echo "1" > /sys/bus/scsi/drivers/sd/${device}/rescan; |
| done |
| |
| sleep 3 |
| |
| multipathd reconfigure |
| |
| sleep 3 |
| |
| # cleanup any old/faulty paths |
| delete_needed=false |
| multipath -l 3${WWID} |
| for dev in $(multipath -l 3${WWID} 2>/dev/null| grep failed | awk '{print $3}' ); do |
| logger -t "CS_SCSI_VOL_FIND" "${WWID} multipath contains faulty path ${dev}, removing" |
| echo 1 > /sys/block/${dev}/device/delete; |
| delete_needed=true |
| done |
| |
| if [ "${delete_needed}" == "true" ]; then |
| sleep 10 |
| multipath -v2 >/dev/null |
| fi |
| |
| multipath -l 3${WWID} |
| |
| logger -t "CS_SCSI_VOL_FIND" "${WWID} successfully discovered and available" |
| |
| echo "$(date): Complete - found mapped LUN at /dev/mapper/3${WWID}" |
| |
| exit 0 |