mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	This PR marks the multipath scripts as executable.
This fixes the issue that in 4.19.0.0-RC2, vms can not be stopped in ubuntu hosts.
2024-01-17 12:56:26,061 ERROR [c.c.v.VmWorkJobHandlerProxy] (Work-Job-Executor-4:ctx-e3503563 job-38/job-39 ctx-42706275) (logid:81ede4e9) Invocation exception, caused by: com.cloud.utils.exception.CloudRuntimeException: Unable to stop the virtual machine due to java.lang.NullPointerException
        at com.cloud.utils.script.Script.getExitValue(Script.java:74)
        at com.cloud.hypervisor.kvm.storage.MultipathSCSIAdapterBase.runScript(MultipathSCSIAdapterBase.java:476)
        at com.cloud.hypervisor.kvm.storage.MultipathSCSIAdapterBase.disconnectPhysicalDiskByPath(MultipathSCSIAdapterBase.java:226)
        at com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager.disconnectPhysicalDiskByPath(KVMStoragePoolManager.java:205)
        at com.cloud.hypervisor.kvm.resource.LibvirtComputingResource.cleanupDisk(LibvirtComputingResource.java:3335)
        at com.cloud.hypervisor.kvm.resource.wrapper.LibvirtStopCommandWrapper.execute(LibvirtStopCommandWrapper.java:101)
        at com.cloud.hypervisor.kvm.resource.wrapper.LibvirtStopCommandWrapper.execute(LibvirtStopCommandWrapper.java:49)
        at com.cloud.hypervisor.kvm.resource.wrapper.LibvirtRequestWrapper.execute(LibvirtRequestWrapper.java:78)
        at com.cloud.hypervisor.kvm.resource.LibvirtComputingResource.executeRequest(LibvirtComputingResource.java:1903)
		
	
			
		
			
				
	
	
		
			134 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/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
 |