pax_global_header00006660000000000000000000000064124002135050014502gustar00rootroot0000000000000052 comment=9bb71932cbbcc0a0e3793c82e3715445e58f5d8a qla-tools-20140529/000077500000000000000000000000001240021350500136655ustar00rootroot00000000000000qla-tools-20140529/ql-dynamic-tgt-lun-disc/000077500000000000000000000000001240021350500202335ustar00rootroot00000000000000qla-tools-20140529/ql-dynamic-tgt-lun-disc/COPYING000066400000000000000000000431061240021350500212720ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. qla-tools-20140529/ql-dynamic-tgt-lun-disc/README.ql-dynamic-tgt-lun-disc.txt000066400000000000000000000225241240021350500263030ustar00rootroot00000000000000 Dynamic TGT-LUN Discovery Utility for Linux Readme QLogic Corporation. All rights reserved. Table of Contents 1. Package Contents 2. Requirements 3. OS Support 4. Supported Features 5. Using the Dynamic TGT-LUN Discovery Utility 5.1 Starting the Utility 5.2 Command Line Options 5.3 Menu Options 6. Additional Notes 7. Known Issues and Workarounds 8. Contacting Support 1. Package Contents The Dynamic TGT-LUN Discovery Utility package contains the following: * COPYING - GNU General Public License that describes user rights to copy, distribute, and use the open source content in this Linux tool. * ql-dynamic-tgt-lun-disc.sh - Script file used to scan the QLogic adapters for all the logical unit numbers (LUNs). * README.ql-dynamic-tgt-lun-disc.txt - This readme file. * revision.qldynamic.txt - Text file that identifies the changes made between versions of this package. * sg3_utils-1.23.tgz - Package containing utilities that send SCSI commands to the scsi_devices. 2. Requirements The Dynamic TGT-LUN Discovery Utility (ql-dynamic-tgt-lun-disc.sh) requires one of the Linux platforms listed in section 3, OS Support. 3. OS Support The Dynamic TGT-LUN Discovery Utility for Linux runs on the following OS platforms: * Red Hat RHEL AS 3.0 (32-bit, 64-bit) on Intel x86, Intel EM64T, AMD64 * Red Hat RHEL AS 4.0 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 * Red Hat RHEL AS 5.0 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 * Red Hat RHEL AS 7.0 (32-bit, 64-bit) on Intel IA64, Intel EM64T, x86_64 * Novell SLES 8.0 (32-bit, 64-bit) on x86, AMD64 * Novell SLES 9 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 * Novell SLES 10 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 NOTE: For specific OS service packs (SP) and updates, refer to the descriptions where this software version is posted on the QLogic Web site: http://support.qlogic.com/support/drivers_software.aspx 4. Supported Features The Dynamic TGT-LUN Discovery Utility provides the following features: * Re-scans all the QLogic adapters for new LUNs. * Re-scans and removes lost LUNs from the system. * By default, scans up to 256 LUNs and allows you to set the maximum number of LUNs to scan. * By default, scans all QLogic adapters and allows you to select a specific adapter to scan. * Displays information for each adapter. * Provides an option for proc-based scanning, as an alternative to the default sysfs-based scanning. * Provides an option for extended scanning to rescan the devices whose disk size has changed. * Supports QLogic FC Driver Versions 7.xx.xx and 8.xx.xx. * Also supports QLogic ISCSI Driver Versions 3.xx.xx.xx and 5.xx.xx.xx 5. Using the Dynamic TGT-LUN Discovery Utility This utility scans for newly-added LUNs. After adding new LUNs, you do not need to unload and then reload the QLogic FC driver, or reboot the system. To see the newly-added LUNs, run the ql-dynamic-tgt-lun-disc.sh utility. The following sections describe how to use this utility: * 5.1 Starting the Utility * 5.2 Command Line Options * 5.3 Menu Options 5.1 Starting the Utility To start this utility, run the following command: # ./ql-dynamic-tgt-lun-disc.sh [ -is | --iscsi ] By default, the utility re-scans the QLogic FC adapters for new LUNs. 5.2 Command Line Options -al, --allow-lip Allows the utility to issue the loop initialization processor (LIP) whenever required. By default, the LIP is not issued, even if it is required for scanning LUNs. If the utility does not discover the necessity of LIP, this option is ignored. -cl, --current-luns Displays current LUNs on the system. -e, --extended-scan Rescans the LUNs to identify any change in attributes of existing LUNs. This option can also be used in combination of scan/refresh or maximum LUNs. -h, --help, ? Prints the help text. -i, --interactive Invokes the menu-driven mode of the utility. -is, --iscsi Operates on ISCSI adapters. This option can be used in combination with any other supported option. -m, --max-lun Sets the maximum LUNs to be scanned. -p, --proc Uses the proc file system to perform LUN scanning on the 2.6 kernel. On a 2.4 kernel, the LUN scanning is based on proc file system only. -s, --scan [-r|--refresh] Re-scans all the devices connected to the QLogic adapter. To remove LUNs that are lost, use the -r|--refresh option. CAUTION: Take care when using the Refresh option because it removes the existing LUNs before performing a re-scan. The following examples each list two or three command options that you can use to perform specific operations. Enter only one command. * To re-scan all the adapters: # ./ql-dynamic-tgt-lun-disc.sh # ./ql-dynamic-tgt-lun-disc.sh -s # ./ql-dynamic-tgt-lun-disc.sh --scan * To re-scan and remove any lost LUNs: # ./ql-dynamic-tgt-lun-disc.sh -s -r # ./ql-dynamic-tgt-lun-disc.sh --scan --refresh * To run a proc-based scan of all the adapters: # ./ql-dynamic-tgt-lun-disc.sh -s -p # ./ql-dynamic-tgt-lun-disc.sh --scan --proc * To set the maximum LUNs to be scanned: # ./ql-dynamic-tgt-lun-disc.sh -m 124 # ./ql-dynamic-tgt-lun-disc.sh -s -m 124 * To identify any changes in attributes: # ./ql-dynamic-tgt-lun-disc.sh -e # ./ql-dynamic-tgt-lun-disc.sh --extended-scan * To use the "--extended-scan" option in combination with scan/ refresh and max LUNs: # ./ql-dynamic-tgt-lun-disc.sh -e -s # ./ql-dynamic-tgt-lun-disc.sh -e -r # ./ql-dynamic-tgt-lun-disc.sh -e -s -m 120 * To invoke the menu-driven utility: # ./ql-dynamic-tgt-lun-disc.sh -i # ./ql-dynamic-tgt-lun-disc.sh --interactive * To view the current LUNs on the system: # ./ql-dynamic-tgt-lun-disc.sh -cl # ./ql-dynamic-tgt-lun-disc.sh --current-luns * To view help: # ./ql-dynamic-tgt-lun-disc.sh -h # ./ql-dynamic-tgt-lun-disc.sh --help 5.3 Menu Options The utility provides a menu-driven interface that provides finer control of the operation. To invoke the menu, use the -i or --interactive option with the ql-dynamic-tgt-lun-disc utility. For example: # ./ql-dynamic-tgt-lun-disc.sh -i The following sections describe the utility menus. 5.3.1 MAIN MENU 1: ALL HOSTS SCAN 2: ALL HOST SCAN & REFRESH 3: ALL HOSTS EXTENDED SCAN 4: SELECT HOST TO SCAN 5: SET MAX LUNs TO SCAN (Current: 256) 6: DISPLAY CURRENT LUNS 7: QUIT 1: ALL HOSTS SCAN Scans all the QLogic adapters connected in the system. A message indicates the new LUN found. 2: ALL HOST SCAN & REFRESH Scans all the QLogic adapters connected in the system and removes LUNs that no longer exist. For example, if LUN 1 is seen on Host:2, Bus:0, and Device:0, a corresponding entry exists in /proc/scsi/scsi. For example: Host: scsi2 Channel: 00 Id: 00 Lun: 01 If the LUN is removed, the system still shows the LUN present in /proc/scsi/scsi. To remove any lost LUNS, use this option to re-scan the adapter. 3: ALL HOSTS EXTENDED SCAN Scans all the devices connected to QLogic adapters in the system. This rescans the devices whose disk size has changed. 4: SELECT HOST TO SCAN Invokes the menu to select a specific QLogic adapter to be scanned. (See section 5.3.2.) 5: SET MAX LUNs TO SCAN (Current: 256) Changes the maximum number of LUNs to be scanned. By default, the utility scans a maximum of 256 LUNs. Note[*] : Here default value is set to LUN ID : 256, if LUN ID is greater than 256 and less than 4095, then it will scan the LUN as per need basis, but bydefault it will scan LUN upto 256 6: DISPLAY CURRENT LUNS Shows the current LUNs attached to all QLogic hosts in the system. 7: QUIT Exits the ql-dynamic-tgt-lun-disc utility. 5.3.2 SELECT HOST TO SCAN 1. HOST: scsi2 2. HOST: scsi3 3. SET SCAN TYPE (Current : SCAN ONLY) 4. GO BACK TO PREVIOUS SCREEN 5. QUIT 1. HOST: scsi Specifies the adapter to be scanned. Select this option to start re-scanning the adapter that corresponds to this host number. 2. SET SCAN TYPE Specifies whether re-scanning removes LUNs that no longer exist as a default. By default, the utility re-scans without removing LUNs from the system. Extended scan allows you to scan hosts whose disk size has changed. This option allows you change to "HOST SCAN, REFRESH & EXTENDED SCAN." 3. GO BACK TO PREVIOUS SCREEN Returns to the main menu. 4. QUIT Exits the ql-dynamic-tgt-lun-disc utility. 6. Additional Notes CAUTION: Take care when using the Refresh option because it removes the existing LUNs before it re-scans. 7. Known Issues and Workarounds: None 8. Contacting Support Please feel free to contact your QLogic approved reseller or QLogic Technical Support at any phase of integration for assistance. QLogic Technical Support can be reached by the following methods: Web: http://support.qlogic.com E-mail: support@qlogic.com (c) Copyright 2009. All rights reserved worldwide. QLogic, the QLogic logo, and the Powered by QLogic logo are registered trademarks of QLogic Corporation. All other brand and product names are trademarks or registered trademarks of their respective owners. qla-tools-20140529/ql-dynamic-tgt-lun-disc/ql-dynamic-tgt-lun-disc.sh000077500000000000000000001452141240021350500251470ustar00rootroot00000000000000#!/bin/bash # QLogic FC HBA LUN Scan Utility # Copyright (C) 2006-2014 QLogic Corporation (www.qlogic.com) # #This program is free software; you can redistribute it and/or modify #it under the terms of the GNU General Public License as published by #the Free Software Foundation; either version 2 of the License, or #(at your option) any later version. # #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. # #You should have received a copy of the GNU General Public License #along with this program; if not, write to the Free Software #Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #--------------------------------------------------------------------------# #This script is used to scan the QLogic HBAs for all the LUNs. #By default find all QLogic HBAs and start scanning all targets and all LUNs #---------------------------------------------------------------------------# QL_ATTR_VALUE="Unknown" #Global for storing value QL_HOST=() #list of QL HBAs QL_VHOST=() #list of QL Virtual HBAs QL_TARGETS=() QL_LUNS=() DEVICE_TYPES=(disk tape printer process worm cd\/dvd scanner optical mediumx comms \(0xa\) \(0xb\) storage enclosu "sim dsk" "opti rd" bridge osd adi \(0x13\) \(0x14\) \(0x15\) \(0x16\) \(0x17\) \(0x18\) \(0x19\) \(0x1a\) \(0x1b\) \(0x1c\) \(0x1e\) \(0x18\) \(0x19\) \(0x1a\) \(0x1b\) \(0x1c\) \(0x1e\) wlun "no dev") QL_KERNEL_VERSION=`uname -r` QL_K_MAJ_MIN=`echo ${QL_KERNEL_VERSION} | cut -d . -f -2` QL_PROC_SCSI="/proc/scsi" QL_DRIVER="qla2xxx" QL_SCAN_LUNS=256 QL_CHANNEL=0 QL_REFRESH=0 QL_SCAN=0 QL_INTERACTIVE=0 QL_HELP=0 QL_CURRENT_LUNS=0 QL_SUPPORTED_LUNS=4096 QL_SYSFS=1 QL_PROCFS=2 QL_FS=$QL_SYSFS QL_CALL_RETURNED=2 QL_CALL_AGAIN=3 NOW_FOUND=() NOW_LOST=() TEST_UNIT_READY=1 QL_DISTRUCTIVE_REFRESH=0 QLU_VERSION="2.26" QLU_LUN_SCAN=$0 QL_SUCCESS=0 QL_FAIL=1 QL_TOTAL_HOSTS=0 QL_TOTAL_VHOSTS=0 QL_TOTAL_LUNS=0 QL_TOTAL_TARGETS=0 # Flag to rescan the luns whose disk attributes has changed. QL_EXTENDED_SCAN=0 # Flags to scan FC/ISCSI HBAs. QL_FC_SCAN=0 QL_ISCSI_SCAN=1 QL_HBA_SCAN=${QL_FC_SCAN} #Flags to check which driver is loaded QL_HBA_FC=0 QL_HBA_ISCSI=1 QL_HBA_TYPE=${QL_HBA_FC} TYPE_SCAN_ONLY=1 TYPE_SCAN_REFRESH=2 TYPE_EXTENDED_SCAN_ONLY=3 QL_SCAN_TYPE=$TYPE_SCAN_ONLY # Flags to issue lip on distro drivers QL_HBA_LIP=0 # Variable To extract the sense key after firing #./sg_turs on target devices SENSE_KEY="" # To extract Host_status, after firing ./sg_turs HOST_STATUS="" SG_TUR_VERBOSE="--verbose" SG_TURS="" SG_MAP="" # QL_SG_VERIFICATION values # 0 -- not verified # 1 -- Verified and succesfully # 2 -- Verification failed QL_SG_VERIFICATION=0 # --------------------------------------------------------- # # qlu_sys_find_all_vhost() # # Find virtual hosts for all the physical hosts detected # # Parameter: # # None # # Returns: # # Fill up the QL_VHOST array, returns number of vhosts# # found # # --------------------------------------------------------- # function qlu_sys_find_all_vhost() { #for rhel5 systems QL_VHOST=( `ls /sys/devices/pci*/*/*/host* 2> /dev/null | grep ^host | sed -e "s/.*host//"` ) QL_TOTAL_VHOSTS=${#QL_VHOST[@]} #for rhel6 systems if [ ${#QL_VHOST[@]} -eq 0 ]; then QL_PORT=(`ls /sys/class/fc_host/ 2> /dev/null`) for PORT in `echo ${QL_PORT[@]}` do cat /sys/class/fc_host/$PORT/port_type | grep VPORT &> /dev/null if [ $? -ne 0 ]; then continue fi # Host is vport, check it if is QLogic vport host QL_HOST_LOCAL=(`ls /sys/bus/pci/drivers/$QL_DRIVER/ 2> /dev/null`) for HOST_LOCAL in `echo ${QL_HOST_LOCAL[@]}` do VHOST_LIST=(`ls /sys/bus/pci/drivers/$QL_DRIVER/$HOST_LOCAL/host*/vport-*/ 2> /dev/null`) for VHOST in `echo ${VHOST_LIST[@]}` do if [ $VHOST == $PORT ]; then HOST_NM=`echo $PORT | sed -e "s/.*host//"` QL_VHOST=(${QL_VHOST[@]} $HOST_NM) fi done done done QL_TOTAL_VHOSTS=${#QL_VHOST[@]} fi return } # --------------------------------------------------------- # # qlu_sys_find_all_host() # # Look into the /sys/bus/pci/drivers/qla*/ dir to find all # # HBAs in the system # # Parameter: # # None # # Returns: # # Fill up the QL_HOST array, returns number of hosts # # found # # --------------------------------------------------------- # function qlu_sys_find_all_host() { QL_HOST=( `ls -d /sys/bus/pci/drivers/${SYS_DRIVER}*/*/host* 2> /dev/null | sed -e "s/.*host//"` ) qlu_sys_find_all_vhost # Add Virtual hosts list to the regular array QL_HOST=( ${QL_HOST[@]} ${QL_VHOST[@]} ) QL_TOTAL_HOSTS=${#QL_HOST[@]} return } # --------------------------------------------------------- # # qlu_find_all_host() # # Look into the /proc/scsi/qla2xxx[qla2300] dir to find all # # HBAs in the system # # Parameter: # # None # # Returns: # # Fill up the QL_HBA array, returns number of hosts # # found # # --------------------------------------------------------- # function qlu_find_all_host() { #look into proc file to find all the #HBAs QL_HOST=( `ls ${QL_PROC_SCSI}/${QL_DRIVER}/ 2> /dev/null | grep -v -i "HBA" 2> /dev/null` ) QL_TOTAL_HOSTS=${#QL_HOST[@]} return } # --------------------------------------------------------- # # qlu_is_lun_present() # # Check to see if the LUN is already discovered # # Parameter: # # Host:Channel:Device:Lun # # Returns: # # QL_SUCCESS: If LUN present # # QL_FAIL: If LUN absent # # --------------------------------------------------------- # function qlu_is_lun_present() { local LUN let IN_HOST=$1 let IN_CHANNEL=$2 let IN_DEVICE=$3 let IN_LUN=$4 #check the /proc/scsi/scsi to see if the lun is #present or not #assuming the format of the string would be always # Host: scsi0 Channel: 00 Id: 00 Lun: 00 if [ ${IN_CHANNEL} -lt 10 ]; then IN_CHANNEL="0${IN_CHANNEL}" fi if [ ${IN_DEVICE} -lt 10 ]; then IN_DEVICE="0${IN_DEVICE}" fi if [ ${IN_LUN} -lt 10 ]; then IN_LUN="0${IN_LUN}" fi LUN_STR="Host: scsi${IN_HOST} Channel: ${IN_CHANNEL} Id: ${IN_DEVICE} Lun: ${IN_LUN}" #echo "Looking for LUN: $LUN_STR" cat ${QL_PROC_SCSI}/scsi | grep "$LUN_STR" >& /dev/null if [ $? -eq 0 ]; then return $QL_SUCCESS fi return ${QL_FAIL} } # --------------------------------------------------------- # # qlu_add_lun() # # Calls the add-single-device # # Parameter: # # Host:Channel:Device:Lun # # Returns: # # None # # --------------------------------------------------------- # function qlu_add_lun() { echo "scsi add-single-device $*" > $QL_PROC_SCSI/scsi } # --------------------------------------------------------- # # qlu_remove_lun() # # Calls the remove-single-device # # Parameter: # # Host:Channel:Device:Lun # # Returns: # # None # # --------------------------------------------------------- # function qlu_remove_lun() { echo "scsi remove-single-device $*" > $QL_PROC_SCSI/scsi } # --------------------------------------------------------- # # See if driver scan is done # # Parameter: # # $1: Proc file name # # $2: Host number # # Returns: # # None # # --------------------------------------------------------- # qlu_scan_done() { local PROC_FILE=$1 local HOST=$2 local DELAY=1 local ITERATION=10 echo -n "..." while [ $ITERATION -ge 1 ] do #in any case sleep for 2 secs echo -n "." sleep $DELAY #look for ( 0:17): Total reqs 0, Pending reqs 0, flags cat $PROC_FILE | grep -v "\(.*:[[:space:]]\+0\)" | grep "\(.*\): Total.*flags.*\*.*" >& /dev/null if [ $? -eq 0 ]; then break; fi (( ITERATION -= 1 )) done echo -e "" return } # --------------------------------------------------------- # # qlu_scan_host() # # Scans the host and uses "add-single-device" to add the # # device in OS # # Parameter: # # $*: Space separated list of hosts to be scanned # # Returns: # # None # # --------------------------------------------------------- # function qlu_scan_host() { local LUN test -z "$1" && echo "Host list empty." && return 1; for HOST in $* do #2.4 tell driver to do re-scan first echo "Scanning HOST: scsi${HOST}" PROC_FILE=${QL_PROC_SCSI}/${QL_DRIVER}/${HOST} if [ -e "${PROC_FILE}" ]; then if [ "${QL_HBA_SCAN}" -eq "${QL_FC_SCAN}" ]; then echo "scsi-qlascan" > ${PROC_FILE} fi #call qlu_scan_done to check if scan finished qlu_scan_done ${PROC_FILE} $HOST # get target for this host DEVICES=( `cat ${PROC_FILE} | grep "\-target\-" | sed "s/.*target-\(.*\)=.*/\1/"` ) if [ ${#DEVICES[@]} -eq 0 ]; then echo "No devices attached to HOST: scsi${HOST}" echo "" continue; fi for DEVICE in ${DEVICES[@]} do echo "Scanning DEVICE: ${DEVICE}" #scan all the luns for ((LUN=0; ${LUN} <= ${QL_SCAN_LUNS}; LUN++)) do #check id LUN present qlu_is_lun_present ${HOST} ${QL_CHANNEL} ${DEVICE} ${LUN} WAS_LUN_PRESENT=$? #does user wants to refresh if [ ${QL_REFRESH} -eq 1 ]; then ql_sg_map_n_sg_tur $HOST $DEVICE $LUN if [ "$TEST_UNIT_READY" != "0" ]; then if [ "$SENSE_KEY" == "Illegal Request" ] || [ "$HOST_STATUS" == "DID_NO_CONNECT" ] || [ $QL_DISTRUCTIVE_REFRESH -eq 1 ]; then qlu_remove_lun ${HOST} ${QL_CHANNEL} ${DEVICE} ${LUN} fi fi elif [ ${LUN} -eq 0 ]; then qlu_handle_LUNZ ${HOST} ${QL_CHANNEL} ${DEVICE} fi qlu_add_lun ${HOST} ${QL_CHANNEL} ${DEVICE} ${LUN} #check if a new one found qlu_is_lun_present ${HOST} ${QL_CHANNEL} ${DEVICE} ${LUN} if [ ${WAS_LUN_PRESENT} -ne $? ] && [ ${WAS_LUN_PRESENT} -eq ${QL_FAIL} ]; then echo "Found LUN: ${LUN} on HOST: scsi${HOST}, DEVICE: ${DEVICE}" fi done done else echo "Error: ${PROC_FILE} does not exist..." echo "Skipping scan for HOST: scsi${HOST}..." fi done } # --------------------------------------------------------- # # qlu_display_host_info # # Display the values from /proc/scsi/scsi # # Parameter: # # $1: Host number # # Returns: # # None # # --------------------------------------------------------- # function qlu_display_host_info() { DISPLAY_ALL=0 LOCAL_HOST=( ) if [ "$1" = "" ]; then #display all hosts DISPLAY_ALL=1 fi if [ ${DISPLAY_ALL} -eq 1 ]; then #get list of all hosts first if [ $QL_FS -eq $QL_PROCFS ]; then qlu_find_all_host else qlu_sys_find_all_host fi if [ ${QL_TOTAL_HOSTS} -eq 0 ]; then echo "QLogic Host not found..." echo "Please check if QLogic module is loaded or not..." echo "Aborting display information..." return ${QL_FAIL} fi LOCAL_HOST=( ${QL_HOST[@]} ) else LOCAL_HOST=( $1 ) fi #get a local copy of proc cat ${QL_PROC_SCSI}/scsi > ./local_scsi.txt if [ ! -e "./local_scsi.txt" ]; then echo "Unable to create copy of /proc/scsi/scsi" echo "Aborting display information..." return ${QL_FAIL} fi #read /proc/scsi/scsi for each host DISPLAY_NEXT=0 MAX_DISP_COUNT=2 DISPLAY_COUNT=0 DEVICE_FOUND=0 echo "" for HOST in ${LOCAL_HOST[@]} do while read LINE do if [ ${DISPLAY_NEXT} -eq 1 ]; then if [ ${DISPLAY_COUNT} -eq ${MAX_DISP_COUNT} ]; then DISPLAY_NEXT=0 DISPLAY_COUNT=0 else echo "$LINE" ((DISPLAY_COUNT += 1)) fi fi echo "$LINE" | grep "scsi${HOST}" >& /dev/null if [ $? -eq ${QL_SUCCESS} ]; then echo "$LINE" DEVICE_FOUND=1 DISPLAY_NEXT=1 fi done < ./local_scsi.txt #check if device found if [ ${DEVICE_FOUND} -eq 0 ]; then echo "No device found on Host ${HOST}" else #reset DEVICE_FOUND for next host DEVICE_FOUND=0 fi done rm ./local_scsi.txt >& /dev/null echo "" } # --------------------------------------------------------- # # qlu_display_current_luns() # # Displays luns present currently # # Parameter: None. # # Returns: None. # # --------------------------------------------------------- # function qlu_display_current_luns() { local LUN echo "" echo_b "DEVICE" echo "" echo_b "[H:C:T:L]" echo "" for HOST in ${QL_HOST[@]} do get_targets $HOST for TARGET in ${QL_TARGETS[@]} do get_luns ${HOST} ${TARGET} if [ ${QL_TOTAL_LUNS} -eq 0 ]; then echo "No LUNs on Host$HOST Target$TARGET" else QL_SORTED_LUNS=(`echo ${QL_LUNS[@]} | sed "s/ /\\n/g" | sort -n`) for LUN in ${QL_SORTED_LUNS[@]} do echo_b "[$HOST:0:$TARGET:$LUN]" echo "" done fi done done } # --------------------------------------------------------- # # get_targets () # # Detects all the targets connected to given host and fills # # QL_TARGETS array # # Parameters : # # HOST # # Returns : # # Number of targets # # --------------------------------------------------------- # function get_targets { local HOST=${1} local TARGET local TARGETS=() if [ "${QL_HBA_SCAN}" -eq "${QL_ISCSI_SCAN}" ]; then ls -d /sys/class/scsi_host/host$HOST/device/session*/target* &> /dev/null RET=$? if [ $RET == 0 ]; then TARGETS=(`ls -d /sys/class/scsi_host/host$HOST/device/session*/target$HOST\:0\:* | sed "s/.*target$HOST\:0\://"`) for TARGET in ${TARGETS[@]} do echo "${QL_TARGETS[@]}" | grep -w $TARGET >& /dev/null if [ $? -ne 0 ]; then QL_TARGETS=(${QL_TARGETS[@]} $TARGET) fi done QL_TOTAL_TARGETS=${#QL_TARGETS[@]} return fi fi if [ -e /sys/class/scsi_host/host$HOST/device/ ]; then cd "/sys/class/scsi_host/host$HOST/device/" ls -d rport-$HOST:0-*/target$HOST:0:* &> /dev/null if [ $? -eq 0 ]; then QL_TARGETS=( `ls -d rport-$HOST:0-*/target$HOST:0:* | sed "s/rport.*target${HOST}:0:\(.*\)/\1/"` ) else ls -d rport-$HOST:0-* &> /dev/null if [ $? -eq 0 ]; then QL_TARGETS=( `ls -d rport-$HOST:0-* | sed "s/rport-$HOST:0-//"` ) fi fi ls -d target$HOST:0:* &> /dev/null if [ $? -eq 0 ]; then QL_TARGETS=( `ls -d target$HOST:0:* | sed "s/target$HOST:0://"` ) fi ls -d $HOST:0:* &> /dev/null if [ $? -eq 0 ]; then TARGETS=`ls -d $HOST:0:* | sed "s/$HOST:0:\(.*\):.*/\1/"` for TARGET in ${TARGETS[@]} do echo "${QL_TARGETS[@]}" | grep -w $TARGET >& /dev/null if [ $? -ne 0 ]; then QL_TARGETS=(${QL_TARGETS[@]} $TARGET) fi done fi QL_TOTAL_TARGETS=${#QL_TARGETS[@]} fi return } # --------------------------------------------------------- # # get_proc_targets () # # Detects all the targets connected to given host and fills # # QL_TARGETS array. This works proc based # # Parameters : # # HOST # # Returns : # # Number of targets # # --------------------------------------------------------- # function get_proc_targets { local HOST=$1 local TARGET="" QL_TARGETS=() TARGETS=`cat $HOST | grep "^(.*:" | grep -v "Id:Lun" | sed "s/(\(.*\):.*).*/\1/"` for TARGET in $TARGETS do echo "${QL_TARGETS[@]}" | grep -w $TARGET >& /dev/null if [ $? -ne 0 ]; then QL_TARGETS=(${QL_TARGETS[@]} $TARGET) fi done QL_TOTAL_TARGETS=${#QL_TARGETS[@]} return } # --------------------------------------------------------- # # get_proc_luns () # # Detects all the LUNS connected to given TARGET and fills # # QL_LUNS array, this works on proc based scanning. # # Parameters : # # # # Returns : # # Number of LUNS # # --------------------------------------------------------- # function get_proc_luns { local HOST=$1 local TARGET=$2 local LUN QL_LUNS=() LUNS=`cat $HOST | sed "s/ //g" | grep "^(${TARGET}:" | sed "s/(${TARGET}:\(.*\)).*/\1/"` for LUN in $LUNS do echo "${QL_LUNS}" | grep -w $LUN >& /dev/null if [ $? -ne 0 ]; then QL_LUNS=(${QL_LUNS[@]} $LUN) fi done QL_TOTAL_LUNS=${#QL_LUNS[@]} return } # --------------------------------------------------------- # # get_luns () # # Detects all the LUNS connected to given TARGET and fills # # QL_LUNS array # # Parameters : # # # # Returns : # # Number of LUNS # # --------------------------------------------------------- # function get_luns { local HOST=${1} local TARGET=${2} local LUNS=() if [ "${QL_HBA_SCAN}" -eq "${QL_FC_SCAN}" ]; then if [ -e /sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET} ]; then cd "/sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET}/" elif [ -e /sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET} ]; then cd "/sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET}/" elif [ -e /sys/class/fc_transport/target${HOST}:0:${TARGET}/device ]; then cd "/sys/class/fc_transport/target${HOST}:0:${TARGET}/device/" fi fi if [ "${QL_HBA_SCAN}" -eq "${QL_ISCSI_SCAN}" ]; then if [ -e /sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET} ]; then cd "/sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET}/" elif [ -e /sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET} ]; then cd "/sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET}/" elif [ -e /sys/class/scsi_host/host$HOST/device/session*/target${HOST}:0:${TARGET} ]; then QL_LUNS=(`ls -d /sys/class/scsi_host/host$HOST/device/session*/target$HOST\:0\:$TARGET/$HOST\:0\:$TARGET\:* | sed "s/.*$HOST\:0\:$TARGET\://"`) QL_TOTAL_LUNS=${#QL_LUNS[@]} return fi fi QL_LUNS=( `ls -d $HOST:0:$TARGET:* 2> /dev/null | sed "s/$HOST:0:$TARGET://"` ) QL_TOTAL_LUNS=${#QL_LUNS[@]} return } # --------------------------------------------------------- # # qlu_proc_display_current_luns() # # Displays luns present currently # # using proc filesystem # # Parameter: None. # # Returns: None. # # --------------------------------------------------------- # function qlu_proc_display_current_luns() { local LUN cd "/proc/scsi/$QL_DRIVER" # qlu_scan_host "${QL_HOST[@]}" # return $? for HOST in ${QL_HOST[@]} do get_proc_targets $HOST if [ ${QL_TOTAL_TARGETS} -ne 0 ]; then echo "" echo_b "Device " echo "" echo_b "[H:C:T:L]" echo "" fi for TARGET in ${QL_TARGETS[@]} do get_proc_luns $HOST $TARGET if [ ${QL_TOTAL_LUNS} -ne 0 ]; then QL_SORTED_LUNS=(`echo ${QL_LUNS[@]} | sed "s/ /\\n/g" | sort -n`) for LUN in ${QL_SORTED_LUNS[@]} do echo_b "[$HOST:0:$TARGET:$LUN]" echo "" done else echo "" return 0 fi done done } #-----------------------------------------------------------# # qlu_sys_rescan_scsi_devices() # # Rescan the devices connected to qlogic hosts.This # # rescans the devices whose disk size has changed. # # echo 1 > /sys/block/sd*/device/rescan # # Parameter: # # Host List # # Return : # # None # #-----------------------------------------------------------# function qlu_sys_rescan_scsi_devices() { local LUN local TARGET CWD=`pwd` HOST_LIST=(`echo $1`) for HOST in ${HOST_LIST[@]} do get_targets $HOST for TARGET in ${QL_TARGETS[@]} do get_luns ${HOST} ${TARGET} if [ ${QL_TOTAL_LUNS} -eq 0 ]; then echo "No LUNs on Host$HOST Target$TARGET" else for ((LUN=0; ${LUN} <= ${QL_SCAN_LUNS}; LUN++)) do if [ -e /sys/class/scsi_device/${HOST}:0:${TARGET}:${LUN}/device ]; then sdevice=$(ls block/sd* 2> /dev/null | wc -l) cd "/sys/class/scsi_device/${HOST}:0:${TARGET}:${LUN}/device/" local MAJOR local MINOR if [ -e "block/dev" ]; then MAJOR=`cat "block/dev" | cut -d ":" -f 1` MINOR=`cat "block/dev" | cut -d ":" -f 2` DEV_NAME=`ls -l /dev/ | grep -w "$MAJOR,[[:space:]]\+$MINOR" | sed "s/.* \(.*$\)/\/dev\/\1/" | cut -d / -f 3` if [ -e /sys/block/$DEV_NAME/device/rescan ]; then echo 1 > /sys/block/$DEV_NAME/device/rescan fi elif [ "$sdevice" != 0 ] ; then cd block DEV_NAME=`ls | grep ^sd | cut -d : -f 2` if [ -e /sys/block/$DEV_NAME/device/rescan ]; then echo 1 > /sys/block/$DEV_NAME/device/rescan fi else DEV_NAME=`ls | grep ^block | cut -d : -f 2` if [ -e /sys/block/$DEV_NAME/device/rescan ]; then echo 1 > /sys/block/$DEV_NAME/device/rescan fi fi fi done fi done done cd "$CWD" } # --------------------------------------------------------- # # echo_b() # # Prints messages in bold # # Parameter: # # $1 Message to be printed # # Returns: None. # # --------------------------------------------------------- # function echo_b() { echo -en "\033[1m${1}\033[0m" tput sgr0 } # --------------------------------------------------------- # # qlu_help () # # Prints the help message LUN scan utility # # Parameter: None # # Returns: None # # --------------------------------------------------------- # function qlu_help() { echo "" echo_b "QLogic Linux LUN Scan Utility v$QLU_VERSION" echo "" echo "" echo "To begin scanning the LUNs issue following command:" echo "" echo " # ${QLU_LUN_SCAN}" echo "" echo "Usage: ${QLU_LUN_SCAN} [OPTIONS]" echo "" echo " -al, --allow-lip" echo " LIP is not issued by default, even if it is required for scanning new LUNs" echo " Setting this option, allows the utility to issue LIP." echo "" echo " -cl, --current-luns" echo " Displays LUNS currently present" echo "" echo " -e, --extended-scan" echo " Use this option as \"-e | --extended-scan\". to rescan" echo " LUNs. This will identify any change in attributes of" echo " existing LUNs. This option can be used in combination" echo " of scan/refresh or max luns" echo "" echo " -h, --help, ?" echo " Prints this help message" echo "" echo " -i, --interactive" echo " Use this option to use the menu driven program" echo "" echo " -is, --iscsi " echo " Use this option to operate on ISCSI HBAs, this option can" echo " be used in combination of any other supported option." echo "" echo " -m, --max-lun" echo " To set the maximum LUNs to be scanned" echo "" echo " -p, --proc" echo " Use PROC file system for LUN scanning" echo "" echo " -r, --refresh" echo " To refresh, that is remove LUNs that are lost" echo " use the options \"-r|--refresh\". This will" echo " remove the LUNs which no more exist." echo "" echo " -s, --scan [ -r|--refresh ]" echo " The QLogic LUN scan utility re-scans all the" echo " devices connected to the QLogic HBA" echo "" } # --------------------------------------------------------- # # ql_check_distro () # # Checks if the driver is not a distro release by checking # # for "d" in end # # Parameter: None # # Returns: QL_FAIL/QL_SUCCESS # # --------------------------------------------------------- # function ql_check_distro { local HOST=$1 RET=1 PROC_FILE=${QL_PROC_SCSI}/${QL_DRIVER}/${HOST} if [ -e ${PROC_FILE} ]; then cat /proc/scsi/$QL_DRIVER/$HOST | grep "Driver version" | sed "s/.* version\ //" | grep "d[[:digit:]]" >& /dev/null RET=$? fi return $RET } # --------------------------------------------------------- # # qlu_main () # # The main function to scan the hosts # # Parameter: None # # Returns: Return of scan # # --------------------------------------------------------- # function qlu_main() { if [ $QL_FS == $QL_PROCFS ]; then qlu_find_all_host if [ ${QL_TOTAL_HOSTS} -eq 0 ]; then echo "QLogic Host not found..." echo "Please check if QLogic module is loaded or not..." exit 1 fi qlu_scan_host "${QL_HOST[@]}" return $? else qlu_sys_find_all_host if [ ${QL_TOTAL_HOSTS} -eq 0 ]; then echo "QLogic Host not found..." echo "Please check if QLogic module is loaded or not..." exit 1 fi for HOST in ${QL_HOST[@]} do PROC_FILE=${QL_PROC_SCSI}/${QL_DRIVER}/${HOST} if [ "${QL_HBA_SCAN}" -eq "${QL_FC_SCAN}" ]; then if [ -e ${PROC_FILE} ]; then echo "scsi-qlascan" > ${PROC_FILE} fi fi done #ir-respective of /proc/scsi/qla***/* scan for hosts qlu_sys_scan_host "`echo ${QL_HOST[@]}`" fi } #====Menu Start===== #----------------------------------------# # qlu_hit_any_key() # Waits for user to hist a key # PARAMETERS : NONE # RETURNS : None #----------------------------------------# function qlu_hit_any_key() { echo -n "Hit any key to continue.........." read -n 1 clear } #----------------------------------------# # qlu_main_screen() # Prints the main menu of the program # PARAMETERS : NONE # RETURNS : QL_SUCCESS or QL #----------------------------------------# function qlu_main_screen() { STATUS="" echo " Welcome to QLogic LUN Scan Utility" echo "====================================" echo "" echo "MAIN MENU" echo " 1: ALL HOSTS SCAN" echo " 2: ALL HOST SCAN & REFRESH" echo " 3: ALL HOSTS EXTENDED SCAN" echo " 4: SELECT HOST TO SCAN" echo " 5: SCAN LUN's UPTO (Current LUN # ${QL_SCAN_LUNS})" echo " 6: DISPLAY CURRENT LUNS" echo " 7: QUIT" echo "" echo -n "Please select one of the options above : " read SC1_CHOICE # read user choice for qlu_main_screen case $SC1_CHOICE in 1) echo "" qlu_main echo "" qlu_hit_any_key return $QL_CALL_AGAIN ;; 2) echo "" QL_REFRESH=1 qlu_main echo "" qlu_hit_any_key return $QL_CALL_AGAIN ;; 3) qlu_sys_find_all_host if [ ${QL_TOTAL_HOSTS} -eq 0 ]; then echo "QLogic Host not found..." echo "Please check if QLogic module is loaded or not..." exit 1 fi qlu_sys_rescan_scsi_devices "`echo ${QL_HOST[@]}`" qlu_hit_any_key clear return $QL_CALL_AGAIN ;; 4) STATUS=$QL_CALL_AGAIN clear while [ $STATUS -eq $QL_CALL_AGAIN ] do qlu_screen_2 STATUS=$? done if [ $STATUS -eq $QL_CALL_RETURNED ];then clear return $QL_CALL_AGAIN else return $STATUS fi ;; 5) echo -n "Enter the value for maximum LUN # : " read MAX_LUN qlu_set_max_lun $MAX_LUN if [ $? -eq 2 ]; then qlu_hit_any_key fi clear return $QL_CALL_AGAIN ;; 6) if [ $QL_FS == $QL_PROCFS ]; then qlu_find_all_host if [ ${QL_TOTAL_HOSTS} -eq 0 ]; then echo "QLogic Host not found..." echo "Please check if QLogic module is loaded or not..." exit 1 else qlu_proc_display_current_luns | more fi # qlu_scan_host "${QL_HOST[@]}" # return $? else qlu_sys_find_all_host if [ ${QL_TOTAL_HOSTS} -eq 0 ]; then echo "QLogic Host not found..." echo "Please check if QLogic module is loaded or not..." exit 1 else # cd /sys/class/scsi_device qlu_display_current_luns | more fi fi qlu_hit_any_key clear return $QL_CALL_AGAIN ;; 7 | q | Q | quit) exit 0 ;; *) clear return $QL_CALL_AGAIN ;; esac } #----------------------------------------# # qlu_screen_2() # Prints the Host list # PARAMETERS : NONE # RETURNS : NONE #----------------------------------------# function qlu_screen_2() { #HQ=$QL_HOST # HQ for host quantity HQ=( ) LN=1 # LN for Line Number if [ $QL_FS == $QL_PROCFS ]; then qlu_find_all_host RETURN_VAL=${QL_TOTAL_HOSTS} else qlu_sys_find_all_host RETURN_VAL=${QL_TOTAL_HOSTS} fi if [ $RETURN_VAL -eq 0 ]; then echo "" echo "" echo "No Host found to display" echo "" echo "" else echo "List of available Hosts" fi HQ=( ${QL_HOST[@]} ) for HOST in ${HQ[@]} do echo " $LN. HOST: scsi${HOST}" LN=$((LN+1)) done if [ $QL_SCAN_TYPE -eq 1 ];then SCAN_STATUS="SCAN ONLY" QL_REFRESH=0 elif [ $QL_SCAN_TYPE -eq 2 ];then SCAN_STATUS="SCAN & REFRESH" QL_REFRESH=1 elif [ $QL_SCAN_TYPE -eq 3 ];then SCAN_STATUS="EXTENDED SCAN ONLY" fi echo " $LN. SET SCAN TYPE (Current : $SCAN_STATUS) " echo " $((LN+1)). GO BACK TO PREVIOUS SCREEN" echo " $((LN+2)). QUIT" echo -n "Please select one of the options above : " read SC2_CHOICE # read user choice for qlu_screen_2 case $SC2_CHOICE in q | Q | quit ) exit 0 ;; esac echo "$SC2_CHOICE" | grep "[0-9]\+" >& /dev/null if [ $? -ne 0 ];then clear return $QL_CALL_AGAIN fi if [ $SC2_CHOICE -ge 1 ];then if [ $SC2_CHOICE -le $(($LN-1)) ];then case $QL_SCAN_TYPE in 1 | 2 ) if [ $QL_FS == $QL_PROCFS ]; then qlu_scan_host ${HQ[((SC2_CHOICE-1))]} else qlu_sys_scan_host ${HQ[((SC2_CHOICE-1))]} fi echo "" qlu_hit_any_key return $QL_CALL_AGAIN ;; 3 ) qlu_sys_rescan_scsi_devices ${HQ[((SC2_CHOICE-1))]} echo "" qlu_hit_any_key return $QL_CALL_AGAIN ;; * ) clear return $QL_CALL_AGAIN ;; esac elif [ $SC2_CHOICE -eq $LN ];then STATUS=$QL_CALL_AGAIN clear while [ $STATUS -eq $QL_CALL_AGAIN ] do qlu_screen_4 STATUS=$? done if [ $STATUS -eq $QL_CALL_RETURNED ];then clear return $QL_CALL_AGAIN else return $STATUS fi elif [ $SC2_CHOICE -eq $((LN+1)) ];then return $QL_CALL_RETURNED elif [ $SC2_CHOICE -eq $((LN+2)) ];then exit 0 else return $QL_CALL_AGAIN fi else return $QL_CALL_AGAIN fi } #----------------------------------------# # qlu_screen_32() # Prints the Host list for displaying information # PARAMETERS : Host count $1 # RETURNS : QL_SUCCESS/QL_FAIL #----------------------------------------# function qlu_screen_32() { LN=1 # LN for Line Number echo "List of available Hosts" if [ $QL_FS == $QL_PROCFS ]; then qlu_find_all_host else qlu_sys_find_all_host fi if [ ${QL_TOTAL_HOSTS} -eq 0 ]; then echo "No QLogic HBA found..." echo "Aborting display information..." return ${QL_FAIL} fi for HOST in ${QL_HOST[@]} do echo " $LN. HOST: scsi${HOST}" LN=$((LN+1)) done echo " $LN. GO BACK TO PREVIOUS SCREEN" echo " $((LN+1)). QUIT" echo -n "Please select one of the options above : " read SC2_CHOICE # read user choice for qlu_screen_2 case $SC2_CHOICE in q | Q | quit ) exit 0 ;; esac if [ $SC2_CHOICE -ge 1 ];then if [ $SC2_CHOICE -le ${#QL_HOST[@]} ];then qlu_display_host_info ${QL_HOST[(($SC2_CHOICE - 1))]} | more qlu_hit_any_key return $QL_CALL_AGAIN elif [ $SC2_CHOICE -eq $LN ];then return $QL_CALL_RETURNED elif [ $SC2_CHOICE -eq $((LN+1)) ];then exit 0 else return $QL_CALL_AGAIN fi else return $QL_CALL_AGAIN fi } #----------------------------------------# # qlu_screen_4() # Sets value of $QL_REFRESHED as asked by # user # PARAMETERS : NONE # RETURNS : NONE #----------------------------------------# function qlu_screen_4() { echo "SELECT SCAN TYPE" echo " 1.HOST SCAN & REFRESH" echo " 2.HOST SCAN ONLY" echo " 3.HOST EXTENDED SCAN ONLY" echo -n "Please select one of the options above : " read SC4_CHOICE case $SC4_CHOICE in 1) QL_SCAN_TYPE=$TYPE_SCAN_REFRESH echo "SCAN TYPE SET TO \"SCAN & REFRESH\"" return $QL_CALL_RETURNED ;; 2) QL_SCAN_TYPE=$TYPE_SCAN_ONLY echo "SCAN TYPE SET TO \"SCAN ONLY\"" return $QL_CALL_RETURNED ;; 3) QL_SCAN_TYPE=$TYPE_EXTENDED_SCAN_ONLY echo "SCAN TYPE SET TO \"EXTENDTED SCAN\"" return $QL_CALL_RETURNED ;; q | Q | quit) exit 0 ;; *) return $QL_CALL_AGAIN ;; q | Q | quit ) exit 0 ;; esac } #====Menu End==== #===SysFS Menu=== SG_UTIL_PATH=/tmp/ql/sg_utils mkdir -p "$SG_UTIL_PATH" SG_UTL_DIR=`echo sg3_utils* | sed "s/\(.*\)\.tgz/\1/"` function ql_ask_distructive_scan () { if [ $QL_DISTRUCTIVE_REFRESH == 1 ]; then return 1 fi echo "Would you like to explicitly remove all the devices and rescan ? " echo "Note: This may make the system un-usable if the system is using" echo "any of the devices attached to the QLogic HBAs" echo -n "Proceed? (yes/no): " read CHOICE case ${CHOICE} in yes | y | YES ) QL_DISTRUCTIVE_REFRESH=1 # Reached this point means either proper sg utils was not found # or compilation of SG failed, and user still wants to continue. QL_SG_VERIFICATION=2 return 1 ;; no | n | NO | * ) exit 0 ;; esac } function ql_compile_sg () { if [ -e "`ls | grep -m 1 sg3_utils`" ]; then SG_UTL=`ls | grep -m 1 sg3_utils` if [ -d "$SG_UTIL_PATH/$SG_UTL" ]; then cd "$SG_UTIL_PATH/$SG_UTL" else tar zxvf $SG_UTL -C "$SG_UTIL_PATH" &> /dev/null cd "$SG_UTIL_PATH/$SG_UTL_DIR" fi # Everything is fine till here lets build the source make sg_map sg_turs &> /dev/null RET=$? if [ "$RET" -ne 0 ]; then ql_ask_distructive_scan fi return $RET else echo "ERROR: SG3 Utility not found" echo "Unable to determine devices to be refreshed." ql_ask_distructive_scan return 1 fi } function ql_execute_sg () { TEST_UNIT_READY=1 # Wash out previous value local HOST=$1 local TARGET=$2 local LUN=$3 SENSE_KEY="" HOST_STATUS="" DISK=`$SG_MAP -x | grep -w "$HOST 0 $TARGET $LUN" | cut -d " " -f 10` if [ "$DISK" == "" ]; then DISK=`$SG_MAP -x | grep -w "$HOST 0 $TARGET $LUN" | cut -d " " -f 1` fi if [ "$DISK" != "" ]; then DEVICE_TYPE=`$SG_MAP -x | grep -w "$HOST 0 $TARGET $LUN" | cut -d " " -f 8` if [ "$DEVICE_TYPE" == "" ]; then if [ ! -e /sys/class/scsi_disk/$HOST:0$TARGET:$LUN ]; then return; fi fi # Fail TUR deliberately for controller LUN if [ $DEVICE_TYPE != 12 ] || [ $DEVICE_TYPE != 31 ] || [ $DEVICE_TYPE != 3 ]; then for ((ITERATION=1; ${ITERATION} <= 3; ITERATION++)) do $SG_TURS $DISK $SG_TUR_VERBOSE >& /tmp/ql-util TEST_UNIT_READY=$? SENSE_KEY="`cat /tmp/ql-util | grep "Sense key" | sed "s/.*Sense\ key:\ \(.*\)/\1/"`" HOST_STATUS=`cat /tmp/ql-util | grep -o "DID_NO_CONNECT"` if [ "$SENSE_KEY" == "Unit Attention" ]; then sleep 3 continue else break fi done fi else ql_ask_distructive_scan fi return } function ql_sg_map_n_sg_tur () { local HOST=$1 local TARGET=$2 local LUN=$3 local ATLEAST_ONE_VERBOSE=0 if [ "$QL_DISTRUCTIVE_REFRESH" -eq "1" ]; then TEST_UNIT_READY=1 return fi # Go thru verification only if its never done before if [ $QL_SG_VERIFICATION -eq 0 ]; then SG_IS_THERE=0 # Assuming by default SG Utility is installed # Keep record so we dont end up this function in wrong dir CALL_DIR=`pwd` cd "$ORG_DIR" SG_TURS=`which sg_turs 2> /dev/null` if [ $? -eq 0 ]; then # Though sg_turs is there; check if verbose option is supported, and also which of the --verbose/-v # Checking for --verbose $SG_TURS 2> /dev/null | grep -w "\-\-verbose" &> /dev/null if [ $? -eq 0 ]; then SG_TUR_VERBOSE="--verbose" ATLEAST_ONE_VERBOSE=1 fi # Checking for -v $SG_TURS 2> /dev/null | grep -w "\-v" &> /dev/null if [ $? -eq 0 ]; then SG_TUR_VERBOSE="-v" ATLEAST_ONE_VERBOSE=1 fi # if ATLEAST_ONE_VERBOSE is still 0; this sg_turs is not of our use if [ $ATLEAST_ONE_VERBOSE -eq 0 ]; then SG_IS_THERE=1 # TUR not there fi SG_MAP=`which sg_map 2> /dev/null` if [ $? -ne 0 ]; then SG_IS_THERE=1 # map not there fi else SG_IS_THERE=1 # TUR not there fi if [ $SG_IS_THERE -eq 1 ]; then ql_compile_sg if [ $? -ne 0 ]; then if [ $QL_DISTRUCTIVE_REFRESH -eq 1 ]; then TEST_UNIT_READY=1 fi cd "$CALL_DIR" # we are here means sg utils is not available or usable SG_TURS="" SG_MAPS="" return 1 # Neither sg is available nor we are able to compile else SG_TURS="$SG_UTIL_PATH/$SG_UTL_DIR/sg_turs" SG_MAP="$SG_UTIL_PATH/$SG_UTL_DIR/sg_map" fi fi # Check if SG Module is loaded lsmod | cut -d " " -f 1 | grep sg &> /dev/null if [ $? -ne 0 ]; then # Try to load the module modprobe sg fi # if we are returning from this point then we have successfully verified sg utils # hence no need to do it again for every go QL_SG_VERIFICATION=1 cd "$CALL_DIR" fi # Check if TUR ql_execute_sg $HOST $TARGET $LUN return } # --------------------------------------------------------- # # qlu_sys_remove_lun() # # Removes the device by echoing 1 to /device/delete # # Parameter: # # HOST number # # Returns: # # None # # --------------------------------------------------------- # function qlu_sys_remove_lun () { HOST=$1 DIR=`pwd` cd "/sys/class/scsi_device/" get_targets $HOST for TARGET in ${QL_TARGETS[@]} do get_luns ${HOST} ${TARGET} if [ ${QL_TOTAL_LUNS} -eq 0 ]; then echo "No LUNs found for Host $HOST: Target $TARGET pair" else for ((LUN=0; ${LUN} <= ${QL_SCAN_LUNS}; LUN++)) do echo ${QL_LUNS[@]} | grep -w $LUN &> /dev/null if [ $? -eq 0 ]; then ql_sg_map_n_sg_tur $HOST $TARGET $LUN # Remove only if TUR Fails if [ "$TEST_UNIT_READY" != "0" ]; then # Extract the sense key after firing ./sg_tur. # if key is "Illegal Request", Delete the lun # This condition avoids deleting offline devices if [ "$SENSE_KEY" == "Illegal Request" ] || [ "$HOST_STATUS" == "DID_NO_CONNECT" ] || [ $QL_DISTRUCTIVE_REFRESH -eq 1 ]; then if [ -e /sys/class/scsi_device/$HOST:0:$TARGET:$LUN/device/delete ]; then cd "/sys/class/scsi_device/" echo "1" > $HOST:0:$TARGET:$LUN/device/delete elif [ -e $HOST:0:$TARGET:$LUN/delete ]; then echo "1" > $HOST:0:$TARGET:$LUN/delete fi fi fi fi done fi done cd "$DIR" return } # --------------------------------------------------------- # # ql_issue_lip_n_wait() # # Issues lip and waits for loop state = READY # # /sys/class/scsi_host/host$HOST/scan # # Parameter: # # HOST # # Returns: # # None # # --------------------------------------------------------- # function ql_issue_lip_n_wait { local HOST=$1 #local LOOP_STATE=1 echo "Issuing LIP on host$HOST" if [ -f /sys/class/fc_host/host$HOST/issue_lip ]; then echo "1" > /sys/class/fc_host/host$HOST/issue_lip fi #while [ $LOOP_STATE == 1 ]; #do # cat /proc/scsi/$QL_DRIVER/$HOST | grep "loop state = " # if [ $? == 0 ]; then # LOOP_STATE=0 # echo -n "DONE" # else # echo -n "." # sleep 1 # fi #done } # --------------------------------------------------------- # # ql_clean_LUNZ() # # Removes LUN 0 from the list of array if it's LUNZ # # (Controller LUN) # # using proc filesystem # # Parameter: None. # # Returns: None. # # --------------------------------------------------------- # function ql_clean_LUNZ () { local LUN local MODEL local LUNS_SOURCE=() local LUNS_TEMP=() if [ "$1" == "ORG" ]; then LUNS_SOURCE=( ${LUNS_ORG[@]} ) else LUNS_SOURCE=( ${LUNS_NEW[@]} ) fi for LUN in ${LUNS_SOURCE[@]} do LUN_NO=`echo $LUN | sed "s/.*:.*:.*:\(.*\)/\1/g" 2> /dev/null` if [ "$LUN_NO" == 0 ]; then MODEL_TEMP=`cat /sys/class/scsi_device/$LUN/device/model 2> /dev/null` MODEL=`echo $MODEL_TEMP | sed "s/\ $//g"` if [ "$MODEL" != LUNZ ]; then LUNS_TEMP=( ${LUNS_TEMP[@]} $LUN ) fi else LUNS_TEMP=( ${LUNS_TEMP[@]} $LUN ) fi done if [ $1 == ORG ]; then LUNS_ORG=( ${LUNS_TEMP[@]} ) else LUNS_NEW=( ${LUNS_TEMP[@]} ) fi } # --------------------------------------------------------- # # qlu_sys_scan_host() # # Scans the host by echoing "- - -" to # # /sys/class/scsi_host/host$HOST/scan # # Parameter: # # HOST/HOST list # # Returns: # # None # # --------------------------------------------------------- # function qlu_sys_scan_host () { local TARGET local LUN HOST_LIST=(`echo $1`) local DIR=`pwd` cd "/sys/class/scsi_device/" echo "SCAN LUNs upto: ${QL_SCAN_LUNS}" for HOST in ${HOST_LIST[@]} do LUNS_ORG=( `ls -d $HOST* 2> /dev/null` ) ql_clean_LUNZ ORG if [ $QL_REFRESH -eq 1 ]; then qlu_sys_remove_lun $HOST else qlu_handle_LUNZ $HOST fi if [ "$QL_HBA_LIP" == 1 ]; then if [ "${QL_HBA_SCAN}" -eq "${QL_FC_SCAN}" ]; then #ql_check_distro $HOST #if [ $? -eq 0 ]; then ql_issue_lip_n_wait $HOST #fi fi fi if [ -e /sys/class/scsi_host/host$HOST/scan ]; then echo "Scanning HOST: host${HOST}" PROC_FILE=${QL_PROC_SCSI}/${QL_DRIVER}/${HOST} if [ -e ${PROC_FILE} ]; then #call qlu_scan_done to check if scan finished qlu_scan_done ${PROC_FILE} $HOST fi #if not equalto default LUNS to scan if [ $QL_SCAN_LUNS -ne 256 ]; then for ((LUN=0; ${LUN} <= ${QL_SCAN_LUNS}; LUN++)) do echo "- - ${LUN}" > /sys/class/scsi_host/host$HOST/scan done else echo '- - -' > /sys/class/scsi_host/host$HOST/scan fi LUNS_NEW=( `ls -d $HOST* 2> /dev/null` ) ql_clean_LUNZ NEW for LUN in `echo ${LUNS_NEW[@]}` do echo ${LUNS_ORG[@]} | grep -w $LUN &> /dev/null if [ $? -ne 0 ]; then NOW_FOUND=( ${NOW_FOUND[@]} "$LUN\\n" ) fi done for LUN in `echo ${LUNS_ORG[@]}` do echo ${LUNS_NEW[@]} | grep -w $LUN &> /dev/null if [ $? -ne 0 ]; then NOW_LOST=( ${NOW_LOST[@]} "$LUN\\n" ) fi done ls $HOST:0:* &> /dev/null if [ $? -ne 0 ]; then echo "No devices attached to HOST: host${HOST}" fi else echo "Expected Sysfs attribute" echo "/sys/class/scsi_host/host$HOST/scan not found" fi done if [ ${#NOW_FOUND[@]} -ne 0 ]; then echo -e "Found\n ${NOW_FOUND[@]}" fi if [ ${#NOW_LOST[@]} -ne 0 ]; then echo -e "Removed\n ${NOW_LOST[@]}" fi if [ ${#NOW_LOST[@]} -eq 0 ] && [ ${#NOW_FOUND[@]} -eq 0 ]; then echo -e "No changes discovered in existing devices." fi # Clean the arrays NOW_FOUND=() NOW_LOST=() cd "$DIR" } # --------------------------------------------------------- # # qlu_handle_LUNZ() # # Parameter: # # HOST/Host:Channel:Device # # Returns: # # None # # --------------------------------------------------------- # function qlu_handle_LUNZ () { local HOST=$1 local DIR=`pwd` if [ $QL_FS != $QL_PROCFS ]; then cd "/sys/class/scsi_device/" ls -d $HOST:0:*:0 &> /dev/null if [ $? == 0 ]; then for LUN in `ls -d $HOST:0:*:0` do #if clarion(vendor DGC) remove LUNZ cat ${LUN}/device/vendor | grep -w DGC > /dev/null if [ $? == 0 ]; then cat ${LUN}/device/model | grep -w LUNZ > /dev/null if [ $? == 0 ]; then echo 1 > $LUN/device/delete fi fi done fi cd "$DIR" else cat /proc/scsi/scsi | grep "scsi$HOST.*Id:[[:space:]].*.*Lun:[[:space:]]00" -A 1 | grep "Vendor:" | sed "s/Vendor:[[:space:]]\+\(.*\)[[:space:]]\+Model:[[:space:]]\+.*[[:space:]]\+Rev:[[:space:]]\+.*/\1/" | grep -w "DGC" > /dev/null if [ $? -eq 0 ]; then cat /proc/scsi/scsi | grep "scsi$HOST.*Id:[[:space:]].*.*Lun:[[:space:]]00" -A 1 | grep "Vendor:" | sed "s/Vendor:[[:space:]]\+.*[[:space:]]\+Model:[[:space:]]\+\(.*\)[[:space:]]\+Rev:[[:space:]]\+.*/\1/" | grep -w "LUNZ" > /dev/null if [ $? -eq 0 ]; then qlu_remove_lun ${HOST} ${QL_CHANNEL} ${DEVICE} 0 fi fi fi return } #---------------------------------------------------------- # # qlu_set_max_lun () # # Parameter: # # max-luns to scan # # Returns: # # None # # --------------------------------------------------------- # function qlu_set_max_lun () { MAXLUN=$1 if [ ! -z "$MAXLUN" ]; then echo "$MAXLUN" | grep -w "^[0-9]\+$" >& /dev/null RET1=$? if [ $RET1 -ne 0 ] || [ $MAXLUN -gt $QL_SUPPORTED_LUNS ] || [ $MAXLUN -lt 1 ]; then echo "Error: Invalid value, enter the value in the range [1 - $QL_SUPPORTED_LUNS]" return $QL_CALL_AGAIN else QL_SCAN_LUNS=$MAXLUN fi fi } #===SysFS Menu End=== # Start # Lets check our current DIR, so needed if we need to complie SG utility ORG_DIR=`pwd` if [ ! -d ${QL_PROC_SCSI}/qla2* ] && [ ! -d /sys/module/qla2xxx ]; then QL_HBA_SCAN=${QL_ISCSI_SCAN} else QL_HBA_TYPE=$QL_HBA_ISCSI fi if [ $QL_HBA_TYPE -eq $QL_HBA_FC ]; then if [ ! -d ${QL_PROC_SCSI}/qla4* ] && [ ! -d /sys/module/qla4* ]; then echo " No FC/ISCSI host is found... " exit 1 fi fi #scan input parameters if [ $# -ne 0 ]; then # need to loop thru the args while [ $# -gt 0 ]; do case "$1" in -p | --proc ) QL_FS=${QL_PROCFS} # Make QL_SCAN=0 for any combination like -i -p/-p -i if [ $QL_INTERACTIVE == 1 ]; then QL_SCAN=0 else QL_SCAN=1 fi ;; -h | --help | \? ) QL_HELP=$(($QL_HELP+1)) QL_SCAN=0 ;; -i | --interactive ) QL_INTERACTIVE=$((QL_INTERACTIVE+1)) QL_SCAN=0 ;; -r | --refresh ) QL_REFRESH=$(($QL_REFRESH+1)) QL_SCAN=1 ;; -cl | --current-luns ) QL_CURRENT_LUNS=$((QL_CURRENT_LUNS+1)) QL_SCAN=0 ;; -s | --scan ) QL_SCAN=1 ;; -m | --max-lun ) shift if [ $QL_INTERACTIVE == 0 ]; then QL_SCAN=1 fi qlu_set_max_lun $1 ;; -is | --iscsi ) QL_HBA_SCAN=${QL_ISCSI_SCAN} QL_SCAN=1 ;; -e | --extended-scan ) QL_EXTENDED_SCAN=1 echo $@ | grep "\-p" >& /dev/null if [ $? -eq 0 ] || [ $QL_FS -eq $QL_PROCFS ]; then echo " Proc based extended scanning is not allowed " QL_EXTENDED_SCAN=2 fi ;; -al | --allow-lip ) QL_HBA_LIP=1 # Make QL_SCAN=0 for any combination like -i -al/-al -i if [ $QL_INTERACTIVE == 1 ]; then QL_SCAN=0 else QL_SCAN=1 fi ;; * ) echo "$1 Option not supported" exit 1 ;; esac shift #Check next parameter. done else #by default do the scan QL_SCAN=1 fi #Validate kernel version case ${QL_K_MAJ_MIN} in 2.4) if [ "${QL_HBA_SCAN}" -eq "${QL_FC_SCAN}" ]; then QL_DRIVER="qla2300" else QL_DRIVER="qla4032" fi QL_FS=$QL_PROCFS ;; 2.6 | 3.*) if [ "${QL_HBA_SCAN}" -eq "${QL_FC_SCAN}" ]; then QL_DRIVER=qla2xxx SYS_DRIVER=qla2 else QL_DRIVER=qla4xxx SYS_DRIVER=qla4 fi ;; * ) echo "Kernel ${QL_KERNEL_VERSION} not yet supported."; exit 1 ;; esac QLSCAN_OR_EXTENDEDSCAN=$(($QL_SCAN | $QL_EXTENDED_SCAN)) QL_OPT_TOTAL=$(($QL_HELP+$QL_INTERACTIVE+$QLSCAN_OR_EXTENDEDSCAN+$QL_CURRENT_LUNS)) if [ $QL_OPT_TOTAL != "1" ]; then echo "Please select valid combination of option/s" echo "see $0 -h for help" elif [ $QL_SCAN == 1 ]; then qlu_main elif [ $QL_HELP == 1 ]; then clear qlu_help elif [ $QL_CURRENT_LUNS == 1 ]; then if [ $QL_FS == $QL_PROCFS ]; then qlu_find_all_host if [ ${QL_TOTAL_HOSTS} -eq 0 ]; then echo "QLogic Host not found..." echo "Please check if QLogic module is loaded or not..." exit 1 else qlu_proc_display_current_luns | more fi else qlu_sys_find_all_host if [ ${QL_TOTAL_HOSTS} -eq 0 ]; then echo "QLogic Host not found..." echo "Please check if QLogic module is loaded or not..." exit 1 else qlu_display_current_luns | more fi fi elif [ $QL_INTERACTIVE == 1 ]; then STATUS=$QL_CALL_AGAIN QL_REFRESH=0 # ignore refresh if user has selected along with -i clear while [ $STATUS -eq $QL_CALL_AGAIN ] do qlu_main_screen STATUS=$? done exit 0 fi if [ $QL_EXTENDED_SCAN -eq 1 ];then if [ $QL_FS -eq $QL_PROCFS ]; then echo "ERROR-Extended scan not supported in proc based scanning" else qlu_sys_find_all_host if [ ${QL_TOTAL_HOSTS} -eq 0 ]; then echo "QLogic Host not found..." echo "Please check if QLogic module is loaded or not..." exit 1 fi qlu_sys_rescan_scsi_devices "`echo ${QL_HOST[@]}`" fi fi qla-tools-20140529/ql-dynamic-tgt-lun-disc/revision.qldynamic.txt000066400000000000000000000075371240021350500246260ustar00rootroot00000000000000****************************************** QLogic Dynamic TGT-LUN Discovery Utility ****************************************** Ver: 2.26 SA Apr 15 2014 - Rhel7 support added Ver: 2.25 HZ Dec 16 2013 - Change vport detection logic for RHEL6 and SLES11 - Change vport detection logic for RHEL6 and SLES11 Ver: 2.24 SA Mar 01 2013 - Added support for virtual ports on rhel6 Ver: 2.23 SR Feb 13 2013 - Added support for virtual ports Ver: 2.22 SA Aug 22 2012 - Added supprt for kernel version 3.0 Ver: 2.21 JS Aug 20 2010 - Add echo to show Max LUNs value - Add return for out of range Max LUN value - Error handling when noluns are attached to target - check block sd device dir to rescan for size change - Add changes in readme file for Max LUN scan Ver: 2.21 JS Aug 03 2010 - Additional check to handle LUN removal by mid-layer Ver: 2.20 SR Sep 18 2009 - Display correct message as MAX # of LUNS Ver: 2.19 SR Jun 12 2009 - Have a common logic for processing sg/sd disks Ver: 2.18 SR/RD May 22 2009 - sd device is replaced by sg for sg_turs. - Added the check for scsi device type 0x03h and 0x1Fh. Ver: 2.17 SR May 12 2009 - New README Ver: 2.16 PP Jan 08 2009 - Package contents in README is updated Ver: 2.15 PP Dec 12 2008 - Added newly implemented functions to Main Menu in README. Ver: 2.14 SR Dec 11 2008 - Change logic to check for targets with multiple sessions. Ver: 2.13 PP Nov 21 2008 - Removed qlu_warning_msg function - Correct help message for -al option - Allow issuing LIP on all OS. Ver: 2.12 PP/SR Oct 3 2008 - Check for DID_NO_CONNECT status - Retry sg_turs 3 times for Unit Attention - Add proper paths for tgt delete/detect - Handle the situation where o/p of sg_map is incomplete Ver: 2.11 SR Aug 22 2008 - Correct the variable names - Make sure SG utils are not looked for multiple times - Check if QL_DISTRUCTIVE_REFRESH along with sense_key - Check if delete file exists before echo in it Ver: 2.10 SR Aug 11 2008 - Use bundled SG3 utility if system sg_turs dosen't support verbose mode - Ask user choice for distructive scan if make of SG3 fails Ver: 2.9 PP Jul 30 2008 - Added issuing lip as an option - Added logic to remove devices corresponding to deleted luns, Not the ones which are temporarily down Ver: 2.8 PP Jun 10 2008 - Added extended scan support to RHEL5 Distros - Handle the condition of having spaces in directory names. - Explicit check for combination of extended proc. Ver: 2.7 PP Jun 05 2008 - Added extended scan support to rescan the luns whose disk attributes has changed. Ver: 2.6 PP/SR Apr 30 2008 - Added logic to support RHEL5 inbox ISCSI drivers - Added support for ISCSI drivers - Fix the issue to return more than 256 luns, targets and hosts. - Correct return status from check_distro Ver: 2.5 SR Feb 19 2008 - Added new README Ver: 2.4 SV Mar 15 2007 - Added command line option "max-lun" (ER0000000052424) Ver: 2.3 SR Mar 06 2007 - Included SG Utils (ver 1.23) - In REFRESH use sg_map & sg_turs instead of removing LUNS Ver: 2.2 SV Feb 12 2007 - README file name changed to README.ql-dynamic-tgt-lun-disc.txt Ver: 2.1 SV/SR Jan 25 2007 - Fixed Controller Lun issue for Clariion Ver: 2.0 SV Jan 10, 2007 - Fix the issue of MAX-LUNs - Added display current LUNs - Utility name changed in the README Ver: 1.9 SR Nov 20, 2006 - Check if proc is mounted Ver: 1.8 SR Oct 19, 2006 - Added new README Ver: 1.7 SR Oct 6, 2006 - Renamed ql-lun-scan to ql-dynamic-tgt-lun-disc Ver: 1.6 SR Aug 11, 2006 - Added support for distro drivers. - functions ql_issue_lip & ql_check_distro Ver: 1.5 SR July 4, 2006 - Ignored the controller LUN in wait Ver: 1.4 SR June 26, 2006 - Added logic to wait for driver scan completion Ver: 1.3 SR June 23, 2006 - Added support for SLES 10 Ver: 1.2 LC/SR May 31, 2006 - Ir-respective of /proc/scsi/qla***/* do LUN scan - Added revision file qla-tools-20140529/ql-hba-snapshot/000077500000000000000000000000001240021350500166665ustar00rootroot00000000000000qla-tools-20140529/ql-hba-snapshot/COPYING000066400000000000000000000431061240021350500177250ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. qla-tools-20140529/ql-hba-snapshot/README.ql-hba-snapshot.txt000066400000000000000000000157601240021350500233750ustar00rootroot00000000000000 FC HBA Snapshot Utility Readme QLogic Corporation. All rights reserved. Table of Contents 1. Package Contents 2. Requirements 3. OS Support 4. Supported Features 5. Using the FC HBA Snapshot Utility 5.1 Command Line Options 5.2 Usage Examples 6. Application Notes 7. Known Issues and Workarounds 8. Contacting Support 1. Package Contents The FC HBA Snapshot Utility package contains the following: * COPYING - GNU General Public License that describes user rights to copy, distribute, and use the open source content in this Linux tool. * ql-hba-snapshot.sh - Script file used to display the details of the QLogic adapter attached to the system. * README.ql-hba-snapshot.txt - This readme file. * revision.qlhbasnapshot.txt - Text file that identifies the changes made between versions of this package. 2. Requirements The FC HBA Snapshot Utility requires one of the Linux platforms listed in section 3, OS Support. 3. OS Support The FC HBA Snapshot Utility runs on the following OS platforms: * Red Hat RHEL AS 4.0 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 * Red Hat RHEL AS 5.0 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 * Novell SLES 9 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 * Novell SLES 10 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 NOTE: For specific OS service packs (SP) and updates, refer to the descriptions where this software version is posted on the QLogic Web site: http://support.qlogic.com/support/drivers_software.aspx 4. Supported Features The FC HBA Snapshot Utility provides the following features: * Displays specific information of the adapter, such as world wide port number (WWPN), port ID, and connected targets. * Lists QLogic adapters in the system. * Provides detailed adapter information, including LUNs. * Provides parameters or options that can be passed to the QLogic driver. * Displays statistics for the QLogic host. This option is not available for the standard driver. * Supports Fibre Channel driver version 8.xx.xx. 5. Using the FC HBA Snapshot Utility This utility displays the details of the QLogic adapter attached to the system. It uses one of the two file systems for scanning: proc or sysfs. Displayed details include the following: * QLogic adapter general information * Targets connected to the QLogic host * Details about targets and LUNs * Statistics and parameters * Host list By default, the utility displays specific information for the QLogic adapter, as described in the following sections: * 5.1 Command Line Options * 5.2 Usage Examples 5.1 Command Line Options | <-a/--all> [optional] Provides the of the adapter to display its detailed information. If you do not specify host number, this command shows general information for all hosts. For example: # ./ql-hba-snapshot.sh -h, --help Displays the help text. For example: # ./ql-hba-snapshot.sh --help -hl, --hostlist Displays the list of QLogic hosts (adapters) connected to this system. To obtain the , enter the following command: # ./ql-hba-snapshot.sh --hostlist -p, --parameters Displays the command line parameters that can be passed to the QLogic adapter driver. For example: # ./ql-hba-snapshot.sh --parameters # ./ql-hba-snapshot.sh --procfs --parameters (for procfs) -s, --statistics Displays statistical information for the specified host. The statistics option is only supported in a sysfs-based scan. For example: # ./ql-hba-snapshot.sh --statistics -proc, --procfs Forces the utility to scan procfs-base information, instead of the default sysfs. For example: # ./ql-hba-snapshot.sh --procfs [other valid option] -v, --verbose Enables verbose display. Using this option shows detailed LUN information, in addition to standard information. For example: # ./ql-hba-snapshot.sh --verbose 5.2 Usage Examples The following examples show how to apply the command line options in PROC-based and SYSFS-based file systems. 5.2.1 SYSFS-based File Systems * To display default adapter information, enter the following command: # ./ql-hba-snapshot.sh * To display detailed information of host 7, enter the following command: # ./ql-hba-snapshot.sh 7 * To display detailed information of all hosts, enter the following command: # ./ql-hba-snapshot.sh --all * To display QLogic adapters driver parameters, enter one of the following commands: # ./ql-hba-snapshot.sh -p # ./ql-hba-snapshot.sh --parameters * To display the QLogic adapter, enter one of the following commands: # ./ql-hba-snapshot.sh -hl # ./ql-hba-snapshot.sh --hostlist * To view help, enter one of the following commands: # ./ql-hba-snapshot.sh -h # ./ql-hba-snapshot.sh --help 5.2.2 PROC-based File Systems * To display default adapter information, enter one of the following commands: # ./ql-hba-snapshot.sh -proc # ./ql-hba-snapshot.sh --procfs * To display detailed information of host 7, enter one of the following commands: # ./ql-hba-snapshot.sh -proc 7 # ./ql-hba-snapshot.sh --procfs 7 * To display detailed information of all hosts, enter one of the following commands: # ./ql-hba-snapshot.sh -proc -a # ./ql-hba-snapshot.sh --procfs --all NOTE: The preceding two options both support the -v/--verbose parameter. For example: # ./ql-hba-snapshot.sh -proc -v 7 # ./ql-hba-snapshot.sh --procfs --verbose --all * To display QLogic adapter driver command line parameters, enter one of the following commands: # ./ql-hba-snapshot.sh -proc -p # ./ql-hba-snapshot.sh --procfs --parameters * To display statistics of host 8, enter one of the following commands: # ./ql-hba-snapshot.sh -proc -s 8 # ./ql-hba-snapshot.sh --procfs --statistics 8 * To display QLogic adapters, enter one of the following commands: # ./ql-hba-snapshot.sh -proc -hl # ./ql-hba-snapshot.sh --procfs --hostlist * To view help, enter one of the following commands: # ./ql-hba-snapshot.sh -h # ./ql-hba-snapshot.sh --help 6. Application Notes None 7. Known Issues and Workarounds None 8. Contacting Support Please feel free to contact your QLogic approved reseller or QLogic Technical Support at any phase of integration for assistance. QLogic Technical Support can be reached by the following methods: Web: http://support.qlogic.com E-mail: support@qlogic.com (c) Copyright 2009. All rights reserved worldwide. QLogic, the QLogic logo, and the Powered by QLogic logo are registered trademarks of QLogic Corporation. All other brand and product names are trademarks or registered trademarks of their respective owners. qla-tools-20140529/ql-hba-snapshot/ql-hba-snapshot.sh000077500000000000000000001621461240021350500222400ustar00rootroot00000000000000#!/bin/bash # QLogic FC HBA Snapshot Utility # Copyright (C) 2006 QLogic Corporation (www.qlogic.com) # #This program is free software; you can redistribute it and/or modify #it under the terms of the GNU General Public License as published by #the Free Software Foundation; either version 2 of the License, or #(at your option) any later version. # #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. # #You should have received a copy of the GNU General Public License #along with this program; if not, write to the Free Software #Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #--------------------------------------------------------------------------# #This utility works on the sysfs to display the information of the QLogic #HBA attached in the system. #--------------------------------------------------------------------------# QL_ATTR_VALUE="Unknown" #Global for storing value QL_HOST=() QL_ISCSI_HOST=() QL_TARGETS=() QL_LUNS=() QL_PRINT_LIST=0 QL_PRINT_ALL_DETAILS=0 QL_TABS=0 QL_VERSION=1.16 QL_PROC=1 QL_SYS=2 QL_FS=$QL_SYS QL_MODULE=qla2xxx QL_PROC_PATH=/proc/scsi/$QL_MODULE QL_TEMP=/tmp/temp.scsi INIT_SPACE=0 VERBOSE=0 DEVICE_TYPES=(disk tape printer process worm cd\/dvd scanner optical mediumx comms \(0xa\) \(0xb\) storage enclosu "sim dsk" "opti rd" bridge osd adi \(0x13\) \(0x14\) \(0x15\) \(0x16\) \(0x17\) \(0x18\) \(0x19\) \(0x1a\) \(0x1b\) \(0x1c\) \(0x1e\) \(0x18\) \(0x19\) \(0x1a\) \(0x1b\) \(0x1c\) \(0x1e\) wlun "no dev") QL_SCRIPT=$0 # --------------------------------------------------------- # # echo_b() # # Prints messages in bold # # Parameter: # # $1 Message to be printed # # Returns: None. # # --------------------------------------------------------- # function echo_b() { echo -en "\033[1m${1}\033[0m" tput sgr0 } function qlu_sys_find_iscsi_host() { ls -d /sys/bus/pci/drivers/qla4*/*/host*/ >& /dev/null if [ $? -eq 0 ]; then QL_ISCSI_HOST=( `ls -d /sys/bus/pci/drivers/qla4*/*/host* | sed -e "s/.*host//"` ) else echo_b "QLogic iSCSI HBA not found or sysfs interface not supported" echo "" return 1 fi return ${#QL_ISCSI_HOST[@]} } # --------------------------------------------------------- # # qlu_sys_find_all_host() # # Look into the /sys/bus/pci/drivers/qla*/ dir to find all # # HBAs in the system # # Parameter: # # None # # Returns: # # Fill up the QL_HOST array, returns number of hosts # # found # # --------------------------------------------------------- # function qlu_sys_find_all_host() { ls -d /sys/bus/pci/drivers/qla2*/*/host*/ >& /dev/null if [ $? -eq 0 ]; then #### if [ -e "ls -d /sys/bus/pci/drivers/qla*/*/host*/" ]; then QL_HOST=( `ls -d /sys/bus/pci/drivers/qla2*/*/host* | sed -e "s/.*host//"` ) else ls -d /sys/bus/pci/drivers/qla6*/*/host*/ >& /dev/null if [ $? -eq 0 ]; then QL_HOST=( `ls -d /sys/bus/pci/drivers/qla6*/*/host* | sed -e "s/.*host//"` ) return ${#QL_HOST[@]} fi echo_b "QLogic FC/FCoe HBA not found or sysfs interface not supported" echo "" return 1 fi return ${#QL_HOST[@]} } # --------------------------------------------------------- # # qlu_proc_find_all_host() # # Look into the /proc/scsi/qla2xxx dir to find all # # HBAs in the system # # Parameter: # # None # # Returns: # # Fill up the QL_HOST array, returns number of hosts # # found # # --------------------------------------------------------- # function qlu_proc_find_all_host() { QL_HOST=( `ls` ) return ${#QL_HOST[@]} } # --------------------------------------------------------- # # get_value () # # gets the path as input and returns the value of the # # directed file if not exist returns unknown # # Parameters : # # sysfs path # # Returns : # # value in the file # # --------------------------------------------------------- # function get_value() { QL_ATTR_VALUE="Unknown" if [ $# -eq 0 ]; then echo "Please provide sysfs path" return 1 fi if [ -e $1 ]; then QL_ATTR_VALUE=`cat $1` fi } # --------------------------------------------------------- # # print_value () # # Takes 3 i/ps and and prints # # name = value # # Parameters : # # and # # Returns : # # NONE # # --------------------------------------------------------- # function print_value() { #check all parameters supplied if [ $# -lt 3 ]; then echo "Usage: print_value " fi #print spaces IN_SPACE=$1 while [ $IN_SPACE -gt 0 ] do echo -n " " (( IN_SPACE -= 1 )) done #Print Name echo -en "$2" IN_TAB=$QL_TABS while [ $IN_TAB -gt 0 ] do echo -en "\t" (( IN_TAB -= 1 )) done echo -en ": " #Print Value echo "$3" } # --------------------------------------------------------- # # get_targets () # # Detects all the targets connected to given host and fills # # QL_TARGETS array # # Parameters : # # HOST # # Returns : # # Number of targets # # --------------------------------------------------------- # function get_targets { local HOST=$1 local TARGET local TARGETS=() QL_TARGETS=() #### if [ -e /sys/class/scsi_host/host$HOST/device/ ]; then if [ -e /sys/class/scsi_device ]; then #### cd /sys/class/scsi_host/host$HOST/device/ cd /sys/class/scsi_device/ #### ls -d rport-$HOST:0-* &> /dev/null #### if [ $? -eq 0 ]; then #### QL_TARGETS=( `ls -d rport-$HOST:0-* | sed "s/rport-$HOST:0-//"` ) #### fi ls -d $HOST:0:* &> /dev/null if [ $? -eq 0 ]; then TARGETS=( `ls -d $HOST:0:* | sed "s/$HOST:0:\(.*\):.*/\1/"` ) for TARGET in ${TARGETS[@]} do echo "${QL_TARGETS[@]}" | grep -w $TARGET >& /dev/null if [ $? -ne 0 ]; then QL_TARGETS=(${QL_TARGETS[@]} $TARGET) fi done fi #### ls -d target$HOST:0:* &> /dev/null #### if [ $? -eq 0 ]; then #### QL_TARGETS=( `ls -d target$HOST:0:* | sed "s/target$HOST:0://"` ) #### fi fi cd /sys/class/scsi_host/host$HOST/device/ return ${#QL_TARGETS[@]} } # --------------------------------------------------------- # # get_iscsi_targets () # # Detects all the targets connected to given host and fills # # QL_TARGETS array # # Parameters : # # HOST # # Returns : # # Number of targets # # --------------------------------------------------------- # function get_iscsi_targets { local ISCSI_HOST=$1 local TARGET local TARGETS=() QL_ISCSI_TARGETS=() if [ -e /sys/class/scsi_device ]; then cd /sys/class/scsi_device/ ls -d $ISCSI_HOST:0:* &> /dev/null if [ $? -eq 0 ]; then TARGETS=( `ls -d $ISCSI_HOST:0:* | sed "s/$ISCSI_HOST:0:\(.*\):.*/\1/"` ) for TARGET in ${TARGETS[@]} do echo "${QL_ISCSI_TARGETS[@]}" | grep -w $TARGET >& /dev/null if [ $? -ne 0 ]; then QL_ISCSI_TARGETS=(${QL_ISCSI_TARGETS[@]} $TARGET) fi done fi fi cd /sys/class/scsi_host/host$ISCSI_HOST/device/ return ${#QL_ISCSI_TARGETS[@]} } # --------------------------------------------------------- # # get_proc_targets () # # Detects all the targets connected to given host and fills # # QL_TARGETS array. This works proc based # # Parameters : # # HOST # # Returns : # # Number of targets # # --------------------------------------------------------- # function get_proc_targets { local HOST=$1 local TARGET="" QL_TARGETS=() TARGETS=`cat $HOST | grep "^(.*:" | grep -v "Id:Lun" | sed "s/(\(.*\):.*).*/\1/"` for TARGET in $TARGETS do echo "${QL_TARGETS[@]}" | grep -w $TARGET >& /dev/null if [ $? -ne 0 ]; then QL_TARGETS=(${QL_TARGETS[@]} $TARGET) fi done return ${#QL_TARGETS[@]} } # --------------------------------------------------------- # # get_proc_luns () # # Detects all the LUNS connected to given TARGET and fills # # QL_LUNS array, this works on proc based scanning. # # Parameters : # # # # Returns : # # Number of LUNS # # --------------------------------------------------------- # function get_proc_luns { local HOST=$1 local TARGET=$2 QL_LUNS=() LUNS=`cat $HOST | sed "s/ //g" | grep "^(${TARGET}:" | sed "s/(${TARGET}:\(.*\)).*/\1/"` for LUN in $LUNS do echo "${QL_LUNS}" | grep -w $LUN >& /dev/null if [ $? -ne 0 ]; then QL_LUNS=(${QL_LUNS[@]} $LUN) fi done return ${#QL_LUNS[@]} } # --------------------------------------------------------- # # get_luns () # # Detects all the LUNS connected to given TARGET and fills # # QL_LUNS array # # Parameters : # # # # Returns : # # Number of LUNS # # --------------------------------------------------------- # function get_luns { local HOST=$1 local TARGET=$2 #### if [ -e /sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET} ]; then if [ -e /sys/class/scsi_device/ ]; then cd /sys/class/scsi_device/ #### cd /sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET}/ #### elif [ -e /sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET} ]; then #### cd /sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET}/ fi QL_LUNS=( `ls -d $HOST:0:$TARGET:* 2> /dev/null | sed "s/$HOST:0:$TARGET://"` ) return ${#QL_LUNS[@]} } # --------------------------------------------------------- # # get_iscsi_luns () # # Detects all the LUNS connected to given TARGET and fills # # QL_LUNS array # # Parameters : # # # # Returns : # # Number of LUNS # # --------------------------------------------------------- # function get_iscsi_luns { local HOST=$1 local TARGET=$2 if [ -e /sys/class/scsi_device/ ]; then cd /sys/class/scsi_device/ fi QL_ISCSI_LUNS=( `ls -d $HOST:0:$TARGET:* 2> /dev/null | sed "s/$HOST:0:$TARGET://"` ) return ${#QL_ISCSI_LUNS[@]} } # --------------------------------------------------------- # # common_display () # # Displays common parameters for HBA's # # After version 1.4, Modified for proc too # # Parameters : # # NONE # # --------------------------------------------------------- # function common_iscsi_display { if [ $QL_FS == $QL_SYS ]; then if [ -e /sys/class/iscsi_host/host$ISCSI_HOST ]; then cd /sys/class/iscsi_host/host$ISCSI_HOST fi else if [ -e ${QL_PROC_PATH}/$ISCSI_HOST ]; then cd ${QL_PROC_PATH} fi fi if [ $QL_FS == $QL_SYS ]; then get_value "initiatorname" else echo "" fi print_value $INIT_SPACE "initiatorname" "$QL_ATTR_VALUE" if [ $QL_FS == $QL_SYS ]; then get_value "ipaddress" else echo "" fi print_value $INIT_SPACE "ip address" "$QL_ATTR_VALUE" if [ $QL_FS == $QL_SYS ] && [ -e /sys/module/qla4xxx/ ]; then cd /sys/module/qla4xxx/ fi if [ $QL_FS == $QL_SYS ]; then get_value "version" else echo "" fi print_value $INIT_SPACE "Driver Version" "$QL_ATTR_VALUE" if [ "1" == "0" ]; then if [ $QL_FS == $QL_SYS ]; then get_value "model_name" else echo "" fi print_value $INIT_SPACE "Model" "$QL_ATTR_VALUE" if [ $QL_FS == $QL_SYS ]; then get_value "fw_version" else echo "" fi print_value $INIT_SPACE "Firmware Version" "$QL_ATTR_VALUE" if [ $QL_FS == $QL_SYS ]; then get_value "state" else echo "" fi print_value $INIT_SPACE "Link State" "$QL_ATTR_VALUE" fi } # --------------------------------------------------------- # # common_display () # # Displays common parameters for HBA's # # After version 1.4, Modified for proc too # # Parameters : # # NONE # # --------------------------------------------------------- # function common_display { if [ $QL_FS == $QL_SYS ]; then if [ -e /sys/class/fc_host/host$HOST ]; then cd /sys/class/fc_host/host$HOST fi else #### if [ -e /proc/scsi/$QL_MODULE/$HOST ]; then if [ -e ${QL_PROC_PATH}/$HOST ]; then #### cd /proc/scsi/$QL_MODULE/ cd ${QL_PROC_PATH} fi fi if [ $QL_FS == $QL_SYS ]; then get_value "port_name" else QL_ATTR_VALUE=`cat $HOST | grep "scsi-.*-adapter-port" | sed "s/.*=\(.*\);/\1/"` fi print_value $INIT_SPACE "WWPN" "$QL_ATTR_VALUE" if [ $QL_FS == $QL_SYS ]; then get_value "node_name" else QL_ATTR_VALUE=`cat $HOST | grep "scsi-.*-adapter-node" | sed "s/.*=\(.*\);/\1/"` fi print_value $INIT_SPACE "WWNN" "$QL_ATTR_VALUE" if [ $QL_FS == $QL_SYS ] && [ -e /sys/class/scsi_host/host$HOST/ ]; then cd /sys/class/scsi_host/host$HOST/ fi if [ $QL_FS == $QL_SYS ]; then get_value "driver_version" else QL_ATTR_VALUE=`cat $HOST | grep "Driver" | sed "s/.*Driver\ version\ \(.*\)/\1/"` fi print_value $INIT_SPACE "Driver Version" "$QL_ATTR_VALUE" if [ $QL_FS == $QL_SYS ]; then get_value "model_name" else QL_ATTR_VALUE=`cat $HOST | grep "QLogic.* Host Adapter for " | sed "s/.*QLogic.*Host Adapter for \(.*\):/\1/"` fi print_value $INIT_SPACE "Model" "$QL_ATTR_VALUE" if [ $QL_FS == $QL_SYS ]; then get_value "fw_version" else QL_ATTR_VALUE=`cat $HOST | grep "Firmware version" | sed "s/.*Firmware version \(.*\),.*/\1/"` if [ "$QL_ATTR_VALUE" == "" ]; then QL_ATTR_VALUE="Unknown" fi fi print_value $INIT_SPACE "Firmware Version" "$QL_ATTR_VALUE" if [ $QL_FS == $QL_SYS ]; then get_value "state" else QL_ATTR_VALUE=`cat $HOST | grep "loop state" | sed "s/.*loop state.*<\(.*\)>.*/\1/"` if [ "$QL_ATTR_VALUE" == "" ]; then QL_ATTR_VALUE="Unknown" fi fi print_value $INIT_SPACE "Link State" "$QL_ATTR_VALUE" # In Sysfs these values are printed in verbose option if [ $QL_FS == $QL_PROC ]; then QL_ATTR_VALUE=`cat $HOST | grep "Device queue depth" | sed "s/.*=[[:space:]]\+\(.*\)/\1/"` print_value $INIT_SPACE "Device queue depth" "$QL_ATTR_VALUE" fi if [ $QL_FS == $QL_PROC ]; then cat $HOST | grep "Number of reqs in pending" | sed "s/.*pending_q=\(.*\),.*retry_q=\(.*\),.*done_q=\(.*\),.*scsi_retry_q=\(.*\)/Req in Pending Queue:\1\nReq in Retry Queue:\2\nReq in Done Queue:\3\nReq in SCSI Retry Queue:\4/" fi } # --------------------------------------------------------- # # print_host_headline () # # Prints heading for display # # Parameters : # # Index # # Returns : # # NONE # # --------------------------------------------------------- # function print_host_headline { echo_b "QLogic HBA (FC/FCoe) Host$HOST Information" echo "" } # --------------------------------------------------------- # # print_host_headline () # # Prints heading for display # # Parameters : # # Index # # Returns : # # NONE # # --------------------------------------------------------- # function print_iscsi_host_headline { echo_b "QLogic HBA (iSCSI) Host$ISCSI_HOST Information " echo "" } # --------------------------------------------------------- # # print_target_info () # # Prints target information for given HOST and Target # # Parameters : # # HOST and TARGET # # --------------------------------------------------------- # function print_target_info { HOST=$1 TARGET=$2 if [ $QL_FS == $QL_SYS ]; then if [ -e /sys/class/fc_transport/target$HOST:0:${TARGET}/device/${HOST}:0:${TARGET}:0 ]; then cd /sys/class/fc_transport/target$HOST:0:${TARGET}/device/${HOST}:0:${TARGET}:0 #### if [ -e /sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET}/${HOST}:0:${TARGET}:0 ]; then #### cd /sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET}/${HOST}:0:${TARGET}:0 #### elif [ -e /sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET}/${HOST}:0:${TARGET}:0 ]; then #### cd /sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET}/${HOST}:0:${TARGET}:0 fi else ### if [ -e /proc/scsi/$QL_MODULE/$HOST ]; then if [ -e ${QL_PROC_PATH}/$HOST ]; then ### cd /proc/scsi/$QL_MODULE/ cd ${QL_PROC_PATH} fi fi echo_b "Device : $TARGET" echo "" if [ $QL_FS == $QL_SYS ]; then get_value "vendor" else cat /proc/scsi/scsi | grep -n el > $QL_TEMP LINE=`cat $QL_TEMP | grep "$HOST Channel: 00 Id:.*$TARGET Lun:" -m 1 | sed "s/\(.*\):Host.*/\1/"` LINE=$(($LINE+1)) QL_ATTR_VALUE=`cat $QL_TEMP | grep "^$LINE:" | sed "s/.*Vendor:\(.*\)[[:space:]]\+Rev.*/\1/"` if [ "$QL_ATTR_VALUE" == "" ]; then QL_ATTR_VALUE="Unknown" fi TEMP_MODEL=`cat $QL_TEMP | grep "^$LINE:" | sed "s/.*Model:\(.*\)[[:space:]]\+Rev.*/\1/"` if [ "$TEMP_MODEL" == "" ]; then TEMP_MODEL="Unknown" fi rm -f $QL_TEMP fi print_value $INIT_SPACE "Vendor" $QL_ATTR_VALUE if [ $QL_FS == $QL_SYS ]; then get_value "model" else QL_ATTR_VALUE=$TEMP_MODEL fi print_value $INIT_SPACE "Model" $QL_ATTR_VALUE if [ $QL_FS == $QL_SYS ]; then if [ -e "/sys/class/fc_transport/target${HOST}:0:${TARGET}/device/fc_transport:target${HOST}:0:${TARGET}" ]; then cd /sys/class/fc_transport/target${HOST}:0:${TARGET}/device/fc_transport:target${HOST}:0:${TARGET}/ elif [ -e "/sys/class/fc_transport/target${HOST}:0:${TARGET}/device/fc_transport/target${HOST}:0:${TARGET}" ]; then cd /sys/class/fc_transport/target${HOST}:0:${TARGET}/device/fc_transport/target${HOST}:0:${TARGET}/ fi get_value "port_name" else QL_ATTR_VALUE=`cat $HOST | grep "scsi-.*target-${TARGET}" | sed "s/.*=\(.*\);/\1/"` if [ "$QL_ATTR_VALUE" != "" ]; then TEMP=$QL_ATTR_VALUE QL_ATTR_VALUE="0x${QL_ATTR_VALUE}" fi fi print_value $INIT_SPACE "WWPN" "$QL_ATTR_VALUE" if [ $QL_FS == $QL_SYS ]; then if [ -e /sys/class/fc_transport/target${HOST}:0:${TARGET} ]; then cd /sys/class/fc_transport/target${HOST}:0:${TARGET} fi get_value "port_id" else QL_ATTR_VALUE=`cat $HOST | grep "scsi-.*port.*=.*:${TEMP}" | sed "s/.*=.*:.*:\(.*\):.*;/\1/"` if [ "$QL_ATTR_VALUE" != "" ]; then QL_ATTR_VALUE="0x${QL_ATTR_VALUE}" else QL_ATTR_VALUE="Unknown" fi fi print_value $INIT_SPACE "Port ID" "$QL_ATTR_VALUE" if [ $QL_FS == $QL_SYS ]; then get_luns $HOST $TARGET LUN_QTY=$? else get_proc_luns $HOST $TARGET LUN_QTY=$? fi if [ $LUN_QTY -gt 0 ]; then QL_ATTR_VALUE=$LUN_QTY else QL_ATTR_VALUE="NONE" fi print_value $INIT_SPACE "Number of LUNs" $QL_ATTR_VALUE cd ../../../.. } # --------------------------------------------------------- # # print_target_info () # # Prints target information for given HOST and Target # # Parameters : # # HOST and TARGET # # --------------------------------------------------------- # function print_iscsi_target_info { HOST=$1 TARGET=$2 if [ $QL_FS == $QL_SYS ]; then if [ -e /sys/class/iscsi_host/host$HOST/device/session*/target$HOST:*:$TARGET ]; then cd /sys/class/iscsi_host/host$HOST/device/session*/target$HOST:*:$TARGET/$HOST:*:$TARGET:*/ fi fi if [ $QL_FS == $QL_SYS ]; then cd ../../iscsi_session/session*/ get_value "targetname" cd - >& /dev/null else echo " " fi print_value $INIT_SPACE "targetname" $QL_ATTR_VALUE if [ $QL_FS == $QL_SYS ]; then get_value "state" else echo " " fi print_value $INIT_SPACE "state" $QL_ATTR_VALUE if [ $QL_FS == $QL_SYS ]; then get_value "vendor" else echo " " fi print_value $INIT_SPACE "vendor" $QL_ATTR_VALUE } # --------------------------------------------------------- # # print_lun_heading () # Prints caption to lun information, calculates the space by # reading length of the values # Parameters : # HOST and TARGET # --------------------------------------------------------- # function print_lun_heading () { local HOST=$1 local TARGET=$2 local M_SPACE=0 if [ -e /sys/class/scsi_device/${HOST}:0:${TARGET}:0/device ]; then cd /sys/class/scsi_device/${HOST}:0:${TARGET}:0/device/ else return 1 fi for VALUE in `cat model 2> /dev/null | sed "s/ /./g"` do if [ ${#VALUE} -gt $M_SPACE ]; then M_SPACE=`echo ${#VALUE}` fi done M_SPACE=$((M_SPACE - 4)) echo_b "[H:C:T:L]\tType\tVendor\t Model" while [ $M_SPACE -ge 0 ]; do echo -en " " M_SPACE=$((M_SPACE - 1)) done echo_b "Rev Block Dev\tGeneric Dev" } # --------------------------------------------------------- # # print_iscsi_lun_heading () # Prints caption to lun information, calculates the space by # reading length of the values # Parameters : # HOST and TARGET # --------------------------------------------------------- # function print_iscsi_lun_heading () { local ISCSI_HOST=$1 local TARGET=$2 local M_SPACE=0 local iscsi_luns=() if [ -e /sys/class/scsi_device/ ]; then cd /sys/class/scsi_device/ iscsi_luns=( `ls -d ${ISCSI_HOST}:0:${TARGET}:*` ) echo ${iscsi_luns[@]} | grep -w $1 &> /dev/null if [ $? -eq 0 ]; then cd ${iscsi_luns[0]}/device else return 1 fi else return 1 fi for VALUE in `cat model 2> /dev/null | sed "s/ /./g"` do if [ ${#VALUE} -gt $M_SPACE ]; then M_SPACE=`echo ${#VALUE}` fi done M_SPACE=$((M_SPACE - 4)) echo_b "[H:C:T:L]\tType\tVendor\t Model" while [ $M_SPACE -ge 0 ]; do echo -en " " M_SPACE=$((M_SPACE - 1)) done echo_b "Rev Block Dev\tGeneric Dev" } # --------------------------------------------------------- # # print_proc_lun_heading () # Prints caption to lun information, calculates the space by # reading calculating length of Model value # Parameters : # HOST # --------------------------------------------------------- # function print_proc_lun_heading { local HOST=$1 local M_SPACE=0 local T_SPACE=0 MODEL_LENGTH=`cat /proc/scsi/scsi | grep scsi$HOST -A 2 | grep "Model:.*Rev" -m 1 -o | wc -m` MODEL_LENGTH=$((MODEL_LENGTH-18)) TYPE_LENGTH=`cat /proc/scsi/scsi | grep scsi$HOST -A 2 | grep "Type:.*ANSI" -m 1 -o | wc -m` TYPE_LENGTH=$((TYPE_LENGTH-30)) M_SPACE=$MODEL_LENGTH T_SPACE=$((TYPE_LENGTH-4)) echo_b "[H:C:T:L]\tType" while [ $T_SPACE -ge 0 ]; do echo -en " " T_SPACE=$((T_SPACE - 1)) done echo_b "Vendor\t\tModel" while [ $M_SPACE -ge 0 ]; do echo -en " " M_SPACE=$((M_SPACE - 1)) done echo_b "Rev" } # --------------------------------------------------------- # # print_all_details () # # Prints all details of given host # # Parameters : # # HOST / ALL # # Returns : # # NONE # # --------------------------------------------------------- # function print_all_details { local OPTION=$1 local HOST_LIST=() echo $1 | grep "^[0-9]" &> /dev/null if [ $? -eq 0 ]; then echo ${QL_HOST[@]} | grep -w $1 &> /dev/null if [ $? -ne 0 ]; then echo "ERROR: HOST $1 not found on the system" exit 1 else HOST_LIST=($1) fi elif [ $OPTION == "ALL" ]; then HOST_LIST=( `echo ${QL_HOST[@]}` ) else exit 1 fi for HOST in ${HOST_LIST[@]} do if [ -e /sys/class/fc_host/host$HOST/ ]; then cd /sys/class/fc_host/host$HOST/ fi echo_b "QLogic HBA (FC/FCoe) Host$HOST Information " echo "" get_value "port_name" print_value 0 "WWPN" $QL_ATTR_VALUE get_value "node_name" print_value 0 "WWNN" $QL_ATTR_VALUE if [ -e /sys/class/scsi_host/host$HOST/ ]; then cd /sys/class/scsi_host/host$HOST/ fi get_value "driver_version" print_value 0 "Driver Version" $QL_ATTR_VALUE get_value "fw_version" print_value 0 "Firmware" $QL_ATTR_VALUE get_value "state" print_value 0 "Link State" "$QL_ATTR_VALUE" if [ -e /sys/class/fc_host/host$HOST/ ]; then cd /sys/class/fc_host/host$HOST/ fi get_value "speed" if [ "${QL_ATTR_VALUE}" == "unknown" ] || [ "${QL_ATTR_VALUE}" == "Unknown" ]; then print_value 0 "Speed" "${QL_ATTR_VALUE}" else print_value 0 "Speed" "${QL_ATTR_VALUE}/s" fi get_value "port_id" print_value 0 "Port ID" $QL_ATTR_VALUE get_value "port_type" print_value 0 "Port Type" $QL_ATTR_VALUE local CLASS=() CLASS=(`cat supported_classes 2> /dev/null | sed "s/$/EnD/g"`) CLASS=( `echo ${CLASS[@]} | sed "s/EnD/, /g"`) CLASS=( `echo ${CLASS[@]} | sed "s/,$//"` ) echo "Supported Classes: ${CLASS[@]}" #QL_TABS=0 get_value "tgtid_bind_type" print_value 0 "Target Bind Type" $QL_ATTR_VALUE #QL_TABS=2 if [ -e "/sys/class/fc_host/host$HOST/device/scsi_host:host$HOST/" ]; then cd /sys/class/fc_host/host$HOST/device/scsi_host:host$HOST/ elif [ -e "/sys/class/fc_host/host$HOST/device/scsi_host/host$HOST/" ]; then cd /sys/class/fc_host/host$HOST/device/scsi_host/host$HOST/ fi get_value "zio" print_value 0 "ZIO State" $QL_ATTR_VALUE get_value "zio_timer" print_value 0 "ZIO Timer" "$QL_ATTR_VALUE" get_value "beacon" print_value 0 "Beacon State" "$QL_ATTR_VALUE" #QL_TABS=2 get_targets $HOST if [ $? -ne 0 ]; then echo_b "Device Information" #echo "" fi for TARGET in ${QL_TARGETS[@]} do if [ -e /sys/class/fc_transport/target$HOST:0:$TARGET ]; then cd /sys/class/fc_transport/target$HOST:0:$TARGET fi echo_b "FC_RPORT = ($HOST:0:$TARGET)" echo "" get_value "port_id" print_value $INIT_SPACE "Port ID" $QL_ATTR_VALUE get_value "port_name" print_value $INIT_SPACE "WWPN" $QL_ATTR_VALUE get_value "node_name" print_value $INIT_SPACE "WWNN" $QL_ATTR_VALUE get_luns $HOST $TARGET if [ $? -ne 0 ]; then echo_b "LUN Information [FC/FCoe]" echo "" print_lun_heading $HOST $TARGET echo "" fi QL_SORTED_LUNS=(`echo ${QL_LUNS[@]} | sed "s/ /\\n/g" | sort -n`) for LUN in ${QL_SORTED_LUNS[@]} do #### if [ -e /sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET}/${HOST}:0:${TARGET}:${LUN} ]; then #### cd /sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET}/${HOST}:0:${TARGET}:${LUN} if [ -e /sys/class/scsi_device/${HOST}:0:${TARGET}:${LUN}/device ]; then cd /sys/class/scsi_device/${HOST}:0:${TARGET}:${LUN}/device/ #### elif [ -e /sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET}/${HOST}:0:${TARGET}:${LUN} ]; then #### cd /sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET}/${HOST}:0:${TARGET}:${LUN} fi local MAJOR local MINOR echo_b "[$HOST:0:$TARGET:$LUN]" get_value "type" echo -en "\t${DEVICE_TYPES[$QL_ATTR_VALUE]}" get_value "vendor" echo -en "\t$QL_ATTR_VALUE" get_value "model" echo -en " $QL_ATTR_VALUE" get_value "rev" echo -en " $QL_ATTR_VALUE" get_value "block*/dev" MAJOR=`echo $QL_ATTR_VALUE | cut -d : -f 1` MINOR=`echo $QL_ATTR_VALUE | cut -d : -f 2` DEV_NAME=`ls -l /dev/ | grep -w "$MAJOR,[[:space:]]\+$MINOR" | sed "s/.* \(.*$\)/\/dev\/\1/"` if [ ${#DEV_NAME} -eq 0 ]; then echo -en " " else echo -en " $DEV_NAME" fi get_value "scsi_generic*/dev" MAJOR=`echo $QL_ATTR_VALUE | cut -d : -f 1` MINOR=`echo $QL_ATTR_VALUE | cut -d : -f 2` GDEV_NAME=`ls -l /dev/ | grep -w "$MAJOR,[[:space:]]\+$MINOR" | sed "s/.* \(.*$\)/\/dev\/\1/"` echo -e "\t$GDEV_NAME" if [ $VERBOSE -eq 1 ]; then verbose_attributes $HOST $TARGET $LUN #### get_value "state" #### echo -n "State:$QL_ATTR_VALUE " #### get_value "timeout" #### echo -n " Timeout:$QL_ATTR_VALUE " #QL_TABS=1 #### get_value "queue_depth" #### echo -n " Queue Depth:$QL_ATTR_VALUE " #QL_TABS=2 #### if [ -f iorequest_cnt ] && [ -f iodone_cnt ] && [ -f ioerr_cnt ]; then #### let REQ=`cat iorequest_cnt` #### let DONE=`cat iodone_cnt` #### let ERROR=`cat ioerr_cnt` ##### echo -n " Counts: " ##### echo -n "Req=$REQ," ##### echo -n "Done=$DONE," ##### echo "Error=$ERROR" ##### fi ##### echo "" fi done done done } # --------------------------------------------------------- # # print_iscsi_details () # # Prints all details of given host # # Parameters : # # HOST / ALL # # Returns : # # NONE # # --------------------------------------------------------- # function print_iscsi_details { local OPTION=$1 local HOST_LIST=() echo $1 | grep "^[0-9]" &> /dev/null if [ $? -eq 0 ]; then echo ${QL_ISCSI_HOST[@]} | grep -w $1 &> /dev/null if [ $? -ne 0 ]; then echo "ERROR: HOST $1 not found on the system" exit 1 else HOST_LIST=($1) fi elif [ $OPTION == "ALL" ]; then HOST_LIST=( `echo ${QL_ISCSI_HOST[@]}` ) else exit 1 fi for ISCSI_HOST in ${HOST_LIST[@]} do if [ -e /sys/class/iscsi_host/host$ISCSI_HOST ]; then cd /sys/class/iscsi_host/host$ISCSI_HOST fi echo "" echo_b "QLogic HBA (iSCSI) Host$ISCSI_HOST Information " echo "" get_value "initiatorname" print_value $INIT_SPACE "initiatorname" "$QL_ATTR_VALUE" get_value "ipaddress" print_value $INIT_SPACE "ip address" "$QL_ATTR_VALUE" get_value "hwaddress" print_value $INIT_SPACE "H/w address" "$QL_ATTR_VALUE" if [ -e /sys/module/qla4xxx/ ]; then cd /sys/module/qla4xxx/ fi get_value "version" print_value $INIT_SPACE "driver version" "$QL_ATTR_VALUE" get_iscsi_targets $ISCSI_HOST if [ $? -ne 0 ]; then echo_b "Device Information" fi for TARGET in ${QL_ISCSI_TARGETS[@]} do echo " " if [ -e /sys/class/iscsi_host/host$ISCSI_HOST/device/session*/target$ISCSI_HOST:*:$TARGET ]; then cd /sys/class/iscsi_host/host$ISCSI_HOST/device/session*/iscsi_session/session*/ fi get_value "targetname" print_value $INIT_SPACE "targetname" $QL_ATTR_VALUE get_value "state" print_value $INIT_SPACE "state" $QL_ATTR_VALUE cd /sys/class/iscsi_host/host$ISCSI_HOST/device/session*/\ target$ISCSI_HOST:*:$TARGET/$ISCSI_HOST:*:$TARGET:*/ get_value "vendor" print_value $INIT_SPACE "vendor" $QL_ATTR_VALUE get_iscsi_luns $ISCSI_HOST $TARGET if [ $? -ne 0 ]; then echo_b "LUN Information [iSCSI]" echo "" print_iscsi_lun_heading $ISCSI_HOST $TARGET echo "" fi QL_SORTED_LUNS=(`echo ${QL_ISCSI_LUNS[@]} | \ sed "s/ /\\n/g" | sort -n`) for LUN in ${QL_SORTED_LUNS[@]} do if [ -e /sys/class/scsi_device/${ISCSI_HOST}:0:${TARGET}:${LUN}/device ]; then cd /sys/class/scsi_device/${ISCSI_HOST}:0:${TARGET}:${LUN}/device/ fi local MAJOR local MINOR echo_b "[$ISCSI_HOST:0:$TARGET:$LUN]" get_value "type" echo -en "\t${DEVICE_TYPES[$QL_ATTR_VALUE]}" get_value "vendor" echo -en "\t$QL_ATTR_VALUE" get_value "model" echo -en " $QL_ATTR_VALUE" get_value "rev" echo -en " $QL_ATTR_VALUE" get_value "block*/dev" MAJOR=`echo $QL_ATTR_VALUE | cut -d : -f 1` MINOR=`echo $QL_ATTR_VALUE | cut -d : -f 2` DEV_NAME=`ls -l /dev/ | grep -w "$MAJOR,[[:space:]]\+\ $MINOR" | sed "s/.* \(.*$\)/\/dev\/\1/"` if [ ${#DEV_NAME} -eq 0 ]; then echo -en " " else echo -en " $DEV_NAME" fi get_value "scsi_generic*/dev" MAJOR=`echo $QL_ATTR_VALUE | cut -d : -f 1` MINOR=`echo $QL_ATTR_VALUE | cut -d : -f 2` GDEV_NAME=`ls -l /dev/ | grep -w "$MAJOR,[[:space:]]\+\ $MINOR" | sed "s/.* \(.*$\)/\/dev\/\1/"` echo -e "\t$GDEV_NAME" if [ $VERBOSE -eq 1 ]; then verbose_iscsi_attributes $ISCSI_HOST $TARGET\ $LUN fi done done done } # --------------------------------------------------------- # # verbose_attributes () # # prints the verbose attributes of the scsi device # # Parameters : # # HOST,TARGET,LUN # # Returns : # # None # # --------------------------------------------------------- # function verbose_attributes() { HOST=$1 TARGET=$2 LUN=$3 if [ -e /sys/class/scsi_device/${HOST}:0:${TARGET}:${LUN}/device ]; then cd /sys/class/scsi_device/${HOST}:0:${TARGET}:${LUN}/device/ fi if [ -e state ]; then # change state file for REDHAT get_value "state" echo -n "State:$QL_ATTR_VALUE " elif [ -e online ]; then if [ `cat online` == "0" ]; then echo -n "State:offline " elif [ `cat online` == "1" ]; then echo -n "State:running " fi fi get_value "timeout" echo -n " Timeout:$QL_ATTR_VALUE " #QL_TABS=1 get_value "queue_depth" echo -n " Queue Depth:$QL_ATTR_VALUE " #QL_TABS=2 if [ -f iorequest_cnt ] && [ -f iodone_cnt ] && [ -f ioerr_cnt ]; then let REQ=`cat iorequest_cnt` let DONE=`cat iodone_cnt` let ERROR=`cat ioerr_cnt` echo -n " Counts: " echo -n "Req=$REQ," echo -n "Done=$DONE," echo "Error=$ERROR" fi echo "" } # --------------------------------------------------------- # # verbose_iscsi_attributes () # # prints the verbose attributes of the scsi device # # Parameters : # # HOST,TARGET,LUN # # Returns : # # None # # --------------------------------------------------------- # function verbose_iscsi_attributes() { ISCSI_HOST=$1 TARGET=$2 LUN=$3 if [ -e /sys/class/scsi_device/${ISCSI_HOST}:0:${TARGET}:${LUN}/device ]; then cd /sys/class/scsi_device/${ISCSI_HOST}:0:${TARGET}:${LUN}/device/ fi if [ -e state ]; then # change state file for REDHAT get_value "state" echo -n "State:$QL_ATTR_VALUE " elif [ -e online ]; then if [ `cat online` == "0" ]; then echo -n "State:offline " elif [ `cat online` == "1" ]; then echo -n "State:running " fi fi get_value "timeout" echo -n " Timeout:$QL_ATTR_VALUE " get_value "queue_depth" echo -n " Queue Depth:$QL_ATTR_VALUE " if [ -f iorequest_cnt ] && [ -f iodone_cnt ] && [ -f ioerr_cnt ]; then let REQ=`cat iorequest_cnt` let DONE=`cat iodone_cnt` let ERROR=`cat ioerr_cnt` echo -n " Counts: " echo -n "Req=$REQ," echo -n "Done=$DONE," echo "Error=$ERROR" fi echo "" } # --------------------------------------------------------- # # print_proc_all_details () # # prints the all attributes of the HOST,TARGET,LUN # # Parameters : # # HOST list # # Returns : # # None # # --------------------------------------------------------- # function print_proc_all_details { local OPTION=$1 local HOST_LIST=() echo $1 | grep "^[0-9]" &> /dev/null if [ $? -eq 0 ]; then echo ${QL_HOST[@]} | grep -w $1 &> /dev/null if [ $? -ne 0 ]; then echo "ERROR: HOST $1 not found on the system" exit 1 else HOST_LIST=($1) fi elif [ $OPTION == "ALL" ]; then HOST_LIST=( `echo ${QL_HOST[@]}` ) else exit 1 fi for HOST in ${HOST_LIST[@]} do print_host_headline common_display $HOST get_proc_targets $HOST if [ $? -ne 0 ]; then echo_b "Device Information" #echo "" fi for TARGET in ${QL_TARGETS[@]} do echo_b "FC_RPORT = ($HOST:0:$TARGET)" echo "" QL_ATTR_VALUE=`cat $HOST | grep "scsi-qla.*target-${TARGET}" | sed "s/.*=\(.*\);/\1/"` if [ "${QL_ATTR_VALUE}" != "" ]; then TEMP=$QL_ATTR_VALUE QL_ATTR_VALUE="0x${QL_ATTR_VALUE}" fi print_value $INIT_SPACE "WWPN" "$QL_ATTR_VALUE" QL_ATTR_VALUE=`cat $HOST | grep "scsi-.*port.*=.*:${TEMP}" | sed "s/.*=\(.*\):.*:.*:.*;/\1/"` if [ "${QL_ATTR_VALUE}" != "" ]; then QL_ATTR_VALUE="0x${QL_ATTR_VALUE}" fi print_value $INIT_SPACE "WWNN" "$QL_ATTR_VALUE" QL_ATTR_VALUE=`cat $HOST | grep "scsi-.*port.*=.*:${TEMP}" | sed "s/.*=.*:.*:\(.*\):.*;/\1/"` if [ "${QL_ATTR_VALUE}" != "" ]; then QL_ATTR_VALUE="0x${QL_ATTR_VALUE}" fi print_value $INIT_SPACE "Port ID" "$QL_ATTR_VALUE" get_proc_luns $HOST $TARGET if [ $? -ne 0 ]; then echo_b "LUN Information" echo "" print_proc_lun_heading $HOST echo "" else echo "" return 0 fi for LUN in ${QL_LUNS[@]} do echo_b "[$HOST:0:$TARGET:$LUN]" if [ $LUN -le 9 ]; then TEMP=`cat /proc/scsi/scsi | grep "scsi$HOST.*Id:[[:space:]].${TARGET}.*Lun:[[:space:]]0${LUN}" -A 2 | grep "Type:" | sed "s/Type:[[:space:]]\+\(.*\)[[:space:]]\+ANSI.*/\1/" | sed "s/ //g"` else TEMP=`cat /proc/scsi/scsi | grep "scsi$HOST.*Id:[[:space:]].${TARGET}.*Lun:[[:space:]]${LUN}" -A 2 | grep "Type:" | sed "s/Type:[[:space:]]\+\(.*\)[[:space:]]\+ANSI.*/\1/" | sed "s/ //g"` fi #echo "cat /proc/scsi/scsi | grep scsi$HOST.*Id:[[:space:]].${TARGET}.*Lun:[[:space:]]${LUN} -A 2 | grep Type: | sed s/Type:[[:space:]]\+\(.*\)[[:space:]]\+ANSI.*/\1/ | sed s/ //g" # cat /proc/scsi/scsi | grep "scsi$HOST.*Id:.*${TARGET}.*Lun:[[:space:]]${LUN}" -A 2 | grep "Type:.*Rev:" -o | sed "s/Model:[[:space:]]\+\(.*\)[[:space:]]\+Rev:/\1/" echo -en "\t${TEMP}" TEMP_COUNT=`echo $TEMP | wc -m` TEMP_COUNT=$((TYPE_LENGTH-TEMP_COUNT-1)) while [ $TEMP_COUNT -ge 0 ]; do echo -en " " TEMP_COUNT=$((TEMP_COUNT - 1)) done if [ $LUN -le 9 ]; then cat /proc/scsi/scsi | grep "scsi$HOST.*Id:[[:space:]].${TARGET}.*Lun:[[:space:]]0${LUN}" -A 2 | grep "Vendor:" | sed "s/Vendor:[[:space:]]\+\(.*\)[[:space:]]\+Model:[[:space:]]\+\(.*\)[[:space:]]\+Rev:[[:space:]]\+\(.*\)/\1\t\2\3/" else cat /proc/scsi/scsi | grep "scsi$HOST.*Id:[[:space:]].${TARGET}.*Lun:[[:space:]]${LUN}" -A 2 | grep "Vendor:" | sed "s/Vendor:[[:space:]]\+\(.*\)[[:space:]]\+Model:[[:space:]]\+\(.*\)[[:space:]]\+Rev:[[:space:]]\+\(.*\)/\1\t\2\3/" fi if [ $VERBOSE -eq 1 ]; then verbose_attributes $HOST $TARGET $LUN fi done echo "" done done } # --------------------------------------------------------- # # print_parameters () # # Prints all the parameters for FC host # # Parameters : # # NONE # # Returns : # # NONE # # --------------------------------------------------------- # function print_parameters { if [ -e /sys/module/qla2xxx/parameters ]; then cd /sys/module/qla2xxx/parameters elif [ -e /sys/module/qla2xxx/ ]; then cd /sys/module/qla2xxx/ else return fi echo_b "1. FC HBA Parameters" echo "" echo "" get_value "ql2xlogintimeout" print_value $INIT_SPACE "Login Timeout" $QL_ATTR_VALUE get_value "qlport_down_retry" print_value $INIT_SPACE "Port Down Retry" $QL_ATTR_VALUE get_value "ql2xplogiabsentdevice" print_value $INIT_SPACE "Plogi Absent Device" $QL_ATTR_VALUE get_value "ql2xloginretrycount" print_value $INIT_SPACE "Login Retry Count" $QL_ATTR_VALUE get_value "ql2xfwloadflash" print_value $INIT_SPACE "Load Firmware" $QL_ATTR_VALUE get_value "ql2xfdmienable" print_value $INIT_SPACE "FDMI Enabled" $QL_ATTR_VALUE get_value "ql2xprocessrscn" print_value $INIT_SPACE "Process RSCN" $QL_ATTR_VALUE if [ -f "refcnt" ]; then get_value "refcnt" else get_value "../refcnt" fi print_value $INIT_SPACE "Reference Count" $QL_ATTR_VALUE echo "" } function print_iscsi_parameters { if [ -e /sys/module/qla4xxx/parameters ]; then cd /sys/module/qla4xxx/parameters elif [ -e /sys/module/qla4xxx/ ]; then cd /sys/module/qla4xxx/ else return fi echo "" echo_b "iSCSI HBA Parameters" echo "" get_value "ql4xdiscoverywait" print_value $INIT_SPACE "Discovery Wait" $QL_ATTR_VALUE get_value "ql4xdontresethba" print_value $INIT_SPACE "Rest HBA" $QL_ATTR_VALUE get_value "ql4xenablemsix" print_value $INIT_SPACE "Enable MSI-X" $QL_ATTR_VALUE echo "" } function print_proc_parameters { HOST=$1 echo_b "1. FC HBA $HOST Parameters" echo "" echo "" cat $QL_PROC_PATH/$HOST | grep -w retry cat $QL_PROC_PATH/$HOST | grep -w Timeout local COUNT=`lsmod | grep -w ^$QL_MODULE | sed "s/.*[[:space:]]\+.*[[:space:]]\+\(.*\)[[:space:]]\+.*/\1/"` (( COUNT -= 1 )) echo Reference Count = $COUNT echo -n "Failover = " cat /proc/scsi/qla2xxx/$HOST | grep Driver | sed "s/.*Driver\ version\(.*\)/\1/" | grep "fo" >& /dev/null if [ $? == 0 ]; then echo "Enabled" else echo "Disabled" fi echo "" if [ ${#QL_HOST} -ge "2" ]; then # for single hba this warning would not carry meaning echo "NOTE: These parameters displayed are with reference to HOST$HOST, to display" echo "parameters for other HOST run # $QL_SCRIPT --parameters " fi } # --------------------------------------------------------- # # print_all_host () # # prints all host list # # Parameters : # # NONE # # Returns : # # NONE # # --------------------------------------------------------- # function print_all_host { echo_b "QLogic HBA FC/FCoe List" echo"" local HOST local TEMP=1 for HOST in ${QL_HOST[@]} do echo "$TEMP. HBA $HOST" (( TEMP += 1 )) done #echo "" #echo "To view detailed information of the HBA issue" #echo "# $QL_SCRIPT " #echo "" #exit 0 } # --------------------------------------------------------- # # print_iscsi_host () # # prints all host list # # Parameters : # # NONE # # Returns : # # NONE # # --------------------------------------------------------- # function print_iscsi_host { echo_b "QLogic HBA iSCSI List" echo"" local ISCSI_HOST local TEMP=1 for ISCSI_HOST in ${QL_ISCSI_HOST[@]} do echo "$TEMP. HBA $ISCSI_HOST" (( TEMP += 1 )) done echo "" echo "To view detailed information of the HBA issue" echo "# $QL_SCRIPT " echo "" } function display_help { echo "" echo " | <-a/--all> [optional]" echo " Provide the to display the detailed" echo " information of the HBA." echo " With no option specified, general information of all" echo " hosts will be displayed." echo " Ex." echo " # $QL_SCRIPT " echo " # $QL_SCRIPT --procfs (For procfs)" echo "" echo "-h, --help" echo " Prints the help message." echo " Ex." echo " # $QL_SCRIPT --help" echo "" echo "-hl, --hostlist" echo " This option displays the list of QLogic hosts (HBAs)" echo " connected to this system." echo " The can be obtained by using following command" echo " Ex." echo " # $QL_SCRIPT --hostlist" echo "" echo "-p, --parameters" echo " This option displays the command line parameters that" echo " can be passed to the QLogic HBA driver." echo " Ex." echo " # $QL_SCRIPT --parameters " echo "" echo "-s, --statistics" echo " This option displays the statistical information for" echo " specified host. Stastics option is only supported in" echo " \"sysfs\" based scan." echo " Ex." echo " # $QL_SCRIPT --statistics " echo "" echo "-proc, --procfs" echo " This options forces the the utility to scans information" echo " based on \"procfs\", instead of default sysfs." echo " Ex." echo " # $QL_SCRIPT --procfs [Other valid option]" echo "" echo "-v, --verbose" echo " This enables verbose display. The detailed information" echo " of LUNs will be displayed in addition to standard one." echo " This option is only supported in sysfs." echo " Ex." echo " # $QL_SCRIPT --verbose " echo "" } function print_statistics () { HOST="" local HOST_QTY=$# if [ -e /sys/class/fc_host ]; then cd /sys/class/fc_host else echo "Required information could not be found." return 1 fi for HOST in $@ do echo_b "QLogic HBA Host$HOST Statistics" echo "" if [ -e host$HOST/statistics ]; then cd host$HOST/statistics for FILE in `ls` do VALUE=`cat $FILE 2> /dev/null` if [ $? -eq 0 ]; then echo "$FILE: $VALUE" fi done cd ../.. else echo "Statistics not available for the Host$HOST" fi echo "" done } function print_iscsi_statistics () { for HOST in $@ do echo_b "QLogic HBA Host$HOST Statistics" echo " " echo_b "iscsi statistics not supported for HBA : $HOST" echo " " done echo " " } # Start KERNEL_VERSION=`uname -r` KERNEL_MAJ_MIN=`echo $KERNEL_VERSION | cut -d . -f 1,2` if [ $KERNEL_MAJ_MIN != 2.6 ]; then echo "Only Kernel version 2.6 and above are supported" exit 1 fi QL_MODULES_LOADED=`lsmod | grep -c "^qla"` if [ $QL_MODULES_LOADED -eq 0 ]; then echo "ERROR: Required QLogic modules not loaded" exit 1 fi if [ ! -e ${QL_PROC_PATH} ]; then QL_FS=$QL_SYS fi ls -d /sys/class/fc_host/host*/device >& /dev/null if [ $? -ne 0 ]; then QL_FS=$QL_PROC fi QL_FS=2 if [ "$1" == "-proc" ] || [ "$1" == "--procfs" ]; then QL_FS=$QL_PROC shift fi # Check if desired file system is mounted or not if [ ! -e /sys/ ] && [ $QL_FS == $QL_SYS ]; then echo "ERROR: /sys does not exist" echo " Please make sure sysfs is mounted" exit 1 fi if [ ! -e /proc/ ] && [ $QL_FS == $QL_PROC ]; then echo "ERROR: /proc does not exist" echo " Please make sure sysfs is mounted" exit 1 fi ret_fcoe=0 ret_iscsi=0 echo_b "QLogic HBA-Snapshot Utility." echo "" if [ $QL_FS == $QL_SYS ]; then cd /sys/class/scsi_host >& /dev/null qlu_sys_find_all_host if [ $? -eq 1 ]; then ret_fcoe=1 fi qlu_sys_find_iscsi_host if [ $? -eq 1 ]; then ret_iscsi=1 fi if [ "$ret_fcoe" -eq "1" ] && [ "$ret_iscsi" -eq "1" ]; then echo "exit" exit 1 fi else cd /proc/scsi/qla2xxx >& /dev/null if [ $? -eq 0 ];then qlu_proc_find_all_host else echo_b "QLogic FC HBA not found or proc interface not supported" echo "" exit 1 fi fi RET="" if [ "$1" != "?" ]; then # Check if specific host requested echo $1 | grep "^[0-9]" &> /dev/null RET=$? fi iscsi_flag=0 if [ "$RET" == "0" ]; then HOST_NO=$1 echo ${QL_HOST[@]} | grep -w $1 &> /dev/null if [ $? -ne 0 ]; then echo ${QL_ISCSI_HOST[@]} | grep -w $1 &> /dev/null if [ $? -ne 0 ]; then echo "ERROR: HOST $1 not found on the system" exit 1 else iscsi_flag=1 fi fi # Probably I should modify this function to support proc if [ $QL_FS == $QL_SYS ]; then if [ $iscsi_flag -eq 1 ]; then print_iscsi_details $HOST_NO | more else print_all_details $HOST_NO | more fi else QL_FS=$QL_PROC print_proc_all_details $HOST_NO | more fi exit 0 fi # CASE & VALIDATIONS go here if [ $# -ne 0 ]; then case $1 in -hl | --hostlist ) QL_PRINT_LIST=1 ;; -p | --parameters ) if [ $# -ne 2 ]; then echo "Please select proper option" exit 1 fi iscsi_flag=0 echo $2 | grep "^[0-9]" &> /dev/null if [ $? == 0 ]; then echo ${QL_HOST[@]} | grep -w $2 &> /dev/null if [ $? -ne 0 ]; then echo ${QL_ISCSI_HOST[@]} | grep -w $2\ &> /dev/null if [ $? -ne 0 ]; then echo "ERROR: HOST $2 not found on the\ system" exit 1 else iscsi_flag=1 fi fi if [ $iscsi_flag -eq 1 ] ; then print_iscsi_parameters $2 | more else print_parameters $2 | more fi exit 0 fi if [ $QL_FS == $QL_SYS ]; then print_parameters $2 else if [ "$2" != "" ]; then echo ${QL_HOST[@]} | grep -w $2 &> /dev/null RET=$? if [ "$RET" != "0" ]; then echo "ERROR: HOST $2 not found on the\ system" exit 1 else print_proc_parameters $2 fi else print_proc_parameters ${QL_HOST[0]} fi fi exit 0 ;; -h | --help | ? ) display_help | more exit 0 ;; -a | --all ) QL_PRINT_ALL_DETAILS=1 ;; -v | --verbose ) if [ $# -ne 2 ]; then echo "Please select proper option" echo "# $QL_SCRIPT -v <--all/HOST number>" exit 1 fi #### if [ $QL_FS == $QL_PROC ]; then #### echo "NOTE: Verbose option is effective only in \"sysfs\" based scanning." #### echo " Ignoring verbose option. Press any key to continue...." #### echo "" #### read -s -n 1 #### fi VERBOSE=1 iscsi_flag=0 echo $2 | grep "^[0-9]" &> /dev/null if [ $? == 0 ]; then #### ls -d /sys/class/fc_host/host*/device >& /dev/null #### if [ $? -eq 0 ]; then echo ${QL_HOST[@]} | grep -w $2 &> /dev/null if [ $? -ne 0 ]; then echo ${QL_ISCSI_HOST[@]} |\ grep -w $2 &> /dev/null if [ $? -ne 0 ]; then echo "ERROR: HOST $2 not found on the\ system" exit 1 else iscsi_flag=1 fi fi if [ $iscsi_flag -eq 1 ] ; then print_iscsi_details $2 | more else if [ $QL_FS == $QL_SYS ]; then print_all_details $2 | more else QL_FS=$QL_PROC print_proc_all_details $2 | more fi fi exit 0 elif [ $2 == "-a" ] || [ $2 == "--all" ]; then #### ls -d /sys/class/fc_host/host*/device >& /dev/null #### if [ $? -eq 0 ]; then if [ $QL_FS == $QL_SYS ]; then print_all_details "ALL" | more print_iscsi_details "ALL" | more else QL_FS=$QL_PROC print_proc_all_details "ALL" | more fi exit 0 else echo "Please select proper option" echo "# $QL_SCRIPT -v <--all/HOST number>" exit 1 fi ;; -s | --statistics ) if [ $QL_FS == $QL_PROC ]; then echo "NOTE: Statistics are only available in \"sysfs\" based scanning." echo "Continuing with \"sysfs\" based scan..." QL_FS=$QL_SYS fi if [ $# -ne 2 ]; then echo "Please select proper option" echo "# $QL_SCRIPT --statistics < --all/HOST number >" exit 1 fi echo $2 | grep "^[0-9]" &> /dev/null if [ $? == 0 ]; then echo ${QL_HOST[@]} | grep -w $2 &> /dev/null if [ $? -ne 0 ]; then echo ${QL_ISCSI_HOST[@]} |\ grep -w $2 &> /dev/null if [ $? -ne 0 ]; then echo "ERROR: HOST $2 not found on the\ system" exit 1 else iscsi_flag=1 fi fi if [ $iscsi_flag -eq 1 ] ; then print_iscsi_statistics $2 | more else print_statistics $2 | more fi exit 0 fi if [ $2 == "-a" ] || [ $2 == "--all" ]; then print_statistics "${QL_HOST[@]}" | more print_iscsi_statistics "${QL_ISCSI_HOST[@]}" | more exit 0 else echo "Please select proper option" echo "# $QL_SCRIPT --statistics < --all/HOST number >" exit 1 fi ;; * ) echo "Please select correct option" echo "For help run #$0 --help" exit 1 ;; esac fi if [ $QL_PRINT_LIST == 1 ]; then print_all_host print_iscsi_host exit 0 fi if [ $QL_PRINT_ALL_DETAILS -eq 1 ]; then if [ $QL_FS == $QL_SYS ]; then print_all_details "ALL" | more print_iscsi_details "ALL" | more else print_proc_all_details "ALL" | more fi exit 0 fi #HOST_QTY=$? #PORT_NO=$(( $HOST_QTY - 1 )) for HOST in ${QL_HOST[@]} do print_host_headline #$(( $HOST_QTY - $PORT_NO )) # (( PORT_NO -= 1 )) common_display if [ $QL_FS == $QL_SYS ]; then get_targets $HOST else get_proc_targets $HOST fi if [ $? -ne 0 ]; then echo_b "Device Information" echo "" fi for TARGETS in ${QL_TARGETS[@]} do print_target_info $HOST $TARGETS done echo "" done | more ISCSI_HOST="" for ISCSI_HOST in ${QL_ISCSI_HOST[@]} do print_iscsi_host_headline #$(( $HOST_QTY - $PORT_NO )) # (( PORT_NO -= 1 )) common_iscsi_display if [ $QL_FS == $QL_SYS ]; then get_iscsi_targets $ISCSI_HOST else get_proc_targets $HOST fi if [ $? -ne 0 ]; then echo_b "Device Information" echo "" fi for TARGETS in ${QL_ISCSI_TARGETS[@]} do print_iscsi_target_info $ISCSI_HOST $TARGETS done echo "" done | more exit 0 qla-tools-20140529/ql-hba-snapshot/revision.qlhbasnapshot.txt000066400000000000000000000027111240021350500241340ustar00rootroot00000000000000********************************** QLogic HBA Snapshot Utility ********************************** Ver: 1.16 SR Aug 24 2011 - Correct display message for HBA not found Ver: 1.15 JS Aug 31 2010 - Add iSCSI support for this Utility on sles11sp1 Ver: 1.14 SR May 12 2009 - New README Ver: 1.13 SR Mar 12 2009 - Correct path for model in heading Ver: 1.12 SR Mar 05 2009 - Correct the syntax while checking for "if" condition. Ver 1.11 PP Jan 15 2009 - Added proper paths to display device and host information correctly on RHEL5 and SLES11 distros. Ver 1.10 SR Feb 19 2008 - Added new README Ver 1.9 SR Aug 24 2007 - Fix ER55978 for unwanted output. Ver 1.8 SV/SR Apr 26 2007 - Select different path for QLA6xxx - Added support for PPC64,SLES10,RHEL5 Ver 1.7 SV Feb 12 2007 - README file name changed to README.ql-hba-snapshot.txt Ver 1.6 SV Feb 09, 2006 - Added check for "/proc/scsi/qla2xxx" - Hard coded paths are converted defines - Syntax check done Ver 1.5 SR Dec 05, 2006 - Added support for proc - Some new functions added & some previous functions modified - WWPN & WWNN added in sysfs Ver 1.4 SR Oct 19, 2006 - Added new readme Ver 1.3 SR Oct 6, 2006 - Renamed ql-hba-info to ql-hba-snapshot Ver 1.2 SR June 23, 2006 - Support for SLES10 Ver 1.1 SR June 20, 2006 - Modified display - Added Statistics options - Added -v/--verbose option Ver 1.0 SR/LC June 05, 2006 - First release qla-tools-20140529/ql-lun-state-online/000077500000000000000000000000001240021350500174755ustar00rootroot00000000000000qla-tools-20140529/ql-lun-state-online/COPYING000066400000000000000000000431061240021350500205340ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. qla-tools-20140529/ql-lun-state-online/README.ql-lun-state-online.txt000066400000000000000000000136021240021350500250040ustar00rootroot00000000000000 FC HBA Change LUN State Utility for Linux Readme QLogic Corporation. All rights reserved. Table of Contents 1. Package Contents 2. Requirements 3. OS Support 4. Supported Features 5. Using the FC HBA Change LUN State Utility 5.1 Starting the Utility 5.2 Command Line Options 5.3 Menu Options 6. Application Notes 7. Known Issues and Workarounds 8. Contacting Support 1. Package Contents The FC HBA Change LUN State Utility package contains the following: * COPYING - GNU General Public License that describes user rights to copy, distribute, and use the open source content in this Linux tool. * ql-lun-state-online.sh - Script file used to change the state of LUNs connected to QLogic adapters from offline to online/running. * README.ql-lun-state-online.txt - This readme file. * revision.qllunstateonline.txt - Text file that identifies the changes made between versions of this package. 2. Requirements The FC HBA Change LUN State Utility requires one of the Linux platforms identified in section 3, OS Support. 3. OS Support The FC HBA Change LUN State Utility runs on the following OS platforms: * Red Hat RHEL AS 4.0 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 platforms * Red Hat RHEL AS 5.0 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 platforms * Novell SLES 9 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 platforms * Novell SLES 10 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 platforms NOTE: For specific OS service packs (SP) and updates, refer to the descriptions where this software version is posted on the QLogic Web site: http://support.qlogic.com/support/drivers_software.aspx 4. Supported Features The FC HBA Change LUN State Utility (ql-lun-state-online.sh): * Allows you to select a specific host for enabling LUNs. * Provides an interactive menu, which lets you select a specific LUN. * Enables all offline LUNs with single command. * Lets you select specific targets for every host using a menu. * Supports Fibre Channel driver version 8.xx.xx. 5. Using the FC HBA Change LUN State Utility This utility allows you to change the state of LUNs connected to a QLogic adapter from offline to online/running. The SCSI mid-layer may change a device's state to offline when it does not receive a response from the device. When these devices are offline, the SCSI mid-layer ignores them. For example, if a SCSI command times out on a specific device and fails to recover the device, the SCSI mid-layer marks the device as offline. Later, when the device is online or accessible, you can use the ql-lun-state.sh utility to change the state to running or online. 5.1 Starting the Utility To start this script, enter one of the following commands: # ./ql-lun-state-online.sh # ./ql-lun-state-online.sh --all For example: For /sys/class/scsi_device/2:0:1:4/ HOST number - > 2 For /sys/class/scsi_device/3:0:2:6/ HOST number - > 3 COMMAND: # ./ql-lun-state-online.sh 2 3 This changes the state of all the offline LUNs to running. 5.2 Command Line Options Usage: ./ql-lun-state-online.sh [OPTIONS] Options: HOST NUMBER/S Scans for all offline LUNs on the specified HOSTS and enables them. -a, --all Enables all disabled LUNs. -i, --interactive Starts the menu-driven program. -h, --help, ? Displays help text. Examples: * To enable all LUNs on HOST 2 and 4, enter the following command: # ./ql-lun-state-online.sh 2 4 * To enable all LUNs on all adapters, enter one of the following commands: # ./ql-lun-state-online.sh -a # ./ql-lun-state-online.sh --all * To invoke the menu, enter one of the following commands: # ./ql-lun-state-online.sh -i # ./ql-lun-state-online.sh --interactive * To view help, enter one of the following commands: # ./ql-lun-state-online.sh -h # ./ql-lun-state-online.sh --help 5.3 Menu Options The utility provides a menu-driven interface that provides finer control of the operation. To invoke the menu, use the -i or --interactive option with the ql-lun-state utility. For example: # ./ql-lun-state-online.sh -i The following describes the main menu. MAIN MENU 1. HOST: 2 TGT: 0 LUN: 4 2. HOST: 3 TGT: 1 LUN: 4 3. MAKE ALL ONLINE 4. QUIT Please select any one option: "1. HOST: 2 TGT: 0 LUN: 4" and "2. HOST: 3 TGT: 1 LUN: 4" are system-specific options. These only appear if the QLogic adapter has targets with LUN state "offline." To enable the specified LUN, select the appropriate option. MAIN MENU 1. HOST: 2 TGT: 0 LUN: 4 2. HOST: 3 TGT: 1 LUN: 4 3. MAKE ALL ONLINE 4. QUIT Please select any one option: 2 Modifying to running HOST: 3 TGT: 1 LUN: 4 3. MAKE ALL ONLINE This option enables all offline LUNs. MAIN MENU 1. HOST: 2 TGT: 0 LUN: 4 2. HOST: 3 TGT: 1 LUN: 4 3. MAKE ALL ONLINE 4. QUIT Please select any one option: 3 Found LUN 4 on HOST 2 in offline state Modifying to running Found LUN 4 on HOST 3 in offline state Modifying to running 4. QUIT This option quits the utility. As an alternative, you can quit the utility by typing q or x. 6. Application Notes None 7. Known Issues and Workarounds None 8. Contacting Support Please feel free to contact your QLogic approved reseller or QLogic Technical Support at any phase of integration for assistance. QLogic Technical Support can be reached by the following methods: Web: http://support.qlogic.com E-mail: support@qlogic.com (c) Copyright 2009. All rights reserved worldwide. QLogic, the QLogic logo, and the Powered by QLogic logo are registered trademarks of QLogic Corporation. All other brand and product names are trademarks or registered trademarks of their respective owners. qla-tools-20140529/ql-lun-state-online/ql-lun-state-online.sh000077500000000000000000000173371240021350500236570ustar00rootroot00000000000000#!/bin/bash # QLogic FC HBA Change LUN State Utility # Copyright (C) 2006 QLogic Corporation (www.qlogic.com) # #This program is free software; you can redistribute it and/or modify #it under the terms of the GNU General Public License as published by #the Free Software Foundation; either version 2 of the License, or #(at your option) any later version. # #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. # #You should have received a copy of the GNU General Public License #along with this program; if not, write to the Free Software #Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #--------------------------------------------------------------------------# #This script is used to change the state of LUNS. #The state of LUNS which are disabled can be changed using this script. #This script is useful to enable the LUNS which were marked offline and are now #online. However changing the state from offline to online does not gurantee that #the LUN will become online. #---------------------------------------------------------------------------# QL_SUCCESS=0 QL_FAIL=1 QL_CALL_AGAIN=2 QL_CALL_RETURNED=3 QL_COMMON=0 QL_INVALID=4 all_targets=() HOST=() QLU_VERSION=1.7 QL_FLAG=0 #*****************************************# # echo_b() # # Prints messages in bold # # Parameter: # # $1 Message to be printed # # Returns: None. # #*****************************************# function echo_b() { echo -e "\033[1m${1}\033[0m" tput sgr0 } #*****************************************# # change_lun_state () # # checks for all LUNS which are offline # # and changes their status to running # # or online, # # PARAMETERS : NONE # # RETURNS : $STATUS # #*****************************************# function change_lun_state () { for SEL_HOST in ${HOST[@]} do STATUS=$QL_CALL_AGAIN ls /sys/bus/pci/drivers/qla*/*/host$SEL_HOST &> /dev/null if [ $? -ne 0 ]; then echo "" echo "HOST $SEL_HOST is not a QLogic HBA." STATUS=$QL_INVALID else ls $SEL_HOST:0:* &> /dev/null if [ $? -ne 0 ]; then echo "" echo "No Targets connected to host $SEL_HOST" echo "" STATUS=$QL_INVALID fi fi if [ $STATUS -ne $QL_INVALID ]; then for DEVICE in `ls -d $SEL_HOST*` do LUN=`echo $DEVICE | cut -d : -f 4` cd $DEVICE/device if [ -e state ]; then # change state file for REDHAT if [ `cat state` == "offline" ]; then echo "" echo "Found LUN $LUN on HOST $SEL_HOST in offline state" echo "Modifying to running" echo running > state QL_FLAG=1 fi elif [ -e online ]; then if [ `cat online` == "0" ]; then echo "" echo "Found LUN $LUN on HOST $SEL_HOST in offline state" echo "Modifying to running" echo 1 > online echo 1 > rescan QL_FLAG=1 fi else echo "Sysfs attribute state/online not found" fi cd ../.. done fi done if [ $QL_FLAG == 0 ]; then echo "No Offline LUNs found" fi return $QL_CALL_RETURNED } #*****************************************# # display_help () # # Prints the help message on screen # # PARAMETERS : NONE # # RETURNS : NONE # #*****************************************# function display_help () { clear echo "" echo_b "QLogic Linux LUN STATE Change Utility v$QLU_VERSION" echo "" echo "" echo "Usage: $0 [OPTIONS]" echo "" echo "OPTIONS :" echo "" echo " HOST NUMBER/S" echo " The QLogic LUN STATE change utility" echo " scans for all offline LUNs on the " echo " Specified HOSTS and enables them" echo "" echo " -a, --all " echo " The QLogic LUN STATE change utility " echo " enables all disabled LUNS " echo "" echo " -i, --interactive" echo " Use this option to use the menu driven program" echo "" echo " -h, --help, ?" echo " Prints this help message" echo "" exit 0 } #*****************************************# # qlu_hit_any_key() # Waits for user to hit a key # PARAMETERS : NONE # RETURNS : None #*****************************************# function qlu_hit_any_key() { echo -n "Hit any key to continue......" read -n 1 clear } #*****************************************# # qlu_main_screen () # # Prints the interactive screen and reads# # input from user # # PARAMETERS : NONE # # RETURNS : NONE # #*****************************************# function qlu_main_screen () { clear OFF_LUNS=() ALL_HOSTS=( `ls -d /sys/bus/pci/drivers/qla*/*/host* | sed -e "s/.*host//"` ) for O_HOST in ${ALL_HOSTS[@]} do ls $O_HOST:0:* &> /dev/null if [ $? -eq 0 ]; then # if we are here then targets are connnected to host # Now scan targets for LUNS in `ls -d $O_HOST*` do if [ -e "$LUNS/device/state" ] && [ "`cat $LUNS/device/state`" == "offline" ]; then OFF_LUNS=(${OFF_LUNS[@]} $LUNS) elif [ -e "$LUNS/device/online" ] && [ "`cat $LUNS/device/online`" == "0" ]; then OFF_LUNS=(${OFF_LUNS[@]} $LUNS) fi done fi done LN=1 # line number echo_b "Welcome to QLogic LUN State Change Utility" echo "============================================" echo "" if [ ${#OFF_LUNS[@]} -gt 0 ]; then echo "MAIN MENU" fi for O_LUNS in ${OFF_LUNS[@]} do echo -n " $LN. " echo $O_LUNS | sed "s/\([[:digit:]]\+\):[[:digit:]]\+:\([[:digit:]]\+\):\([[:digit:]]\+\)/HOST: \1 TGT: \2 LUN: \3/" LN=$((LN+1)) done if [ $LN -eq 1 ]; then echo "NO OFFLINE LUNS FOUND " echo "Exiting $0 ..." exit 0 fi echo " $LN. MAKE ALL ONLINE " echo " $((LN+1)). QUIT" echo "" echo -n "Please select any one option : " read SC1_CHOICE case $SC1_CHOICE in q | quit | x ) exit 0 ;; * ) echo $SC1_CHOICE | grep -w "^[0-9]\+$" >& /dev/null if [ $? -ne 0 ]; then return $QL_CALL_AGAIN fi esac if [ $SC1_CHOICE -ge 1 ] && [ $SC1_CHOICE -lt $LN ]; then cd ${OFF_LUNS[((${SC1_CHOICE}-1))]}/device if [ -e "./state" ]; then # change state file for REDHAT/SLES10 echo running > state echo -n "Modifying to running " echo ${OFF_LUNS[((${SC1_CHOICE}-1))]} | sed "s/\([[:digit:]]\+\):[[:digit:]]\+:\([[:digit:]]\+\):\([[:digit:] ]\+\)/HOST: \1 TGT: \2 LUN: \3/" elif [ -e "./online" ]; then #for SLES9 echo -n "Modifying online state to 1 for " echo ${OFF_LUNS[((${SC1_CHOICE}-1))]} | sed "s/\([[:digit:]]\+\):[[:digit:]]\+:\([[:digit:]]\+\):\([[:digit:] ]\+\)/HOST: \1 TGT: \2 LUN: \3/" echo 1 > online echo 1 > rescan else echo "Sysfs attribute state/online not found" fi cd ../.. qlu_hit_any_key return $QL_CALL_AGAIN elif [ $SC1_CHOICE -eq $LN ]; then HOST=( `ls -d /sys/bus/pci/drivers/qla*/*/host* | sed -e "s/.*host//"` ) change_lun_state return $? elif [ $SC1_CHOICE -eq $((LN+1)) ]; then exit 0 else return $QL_CALL_AGAIN fi } # Start cd /sys/class/scsi_device HOST=$* case $HOST in --all | -a ) HOST=( `ls -d /sys/bus/pci/drivers/qla*/*/host* | sed -e "s/.*host//"` ) change_lun_state ;; -i | --interactive ) STATUS=$QL_CALL_AGAIN clear while [ $STATUS -eq $QL_CALL_AGAIN ] do qlu_main_screen STATUS=$? done exit 0 ;; --help | -h | "?" ) display_help ;; *) echo $1 | grep -w "^[0-9]\+$" >& /dev/null if [ $? -ne 0 ]; then echo "" echo "Please enter a valid argument" echo " OR" echo "Please run $0 -h for help" echo "" exit 1 fi change_lun_state ;; esac qla-tools-20140529/ql-lun-state-online/revision.qllunstateonline.txt000066400000000000000000000011221240021350500254700ustar00rootroot00000000000000*********************************** QLogic Change Lun State Utility *********************************** Ver: 1.7 JS Aug 03, 2010 - Add message for Host which has No offline LUNs Ver: 1.6 SR May 12, 2009 - New README Ver: 1.5 SR Feb 19, 2009 - Added new readme Ver: 1.4 SV Feb 12 2007 - README file name changed to README.ql-lun-state-online.txt Ver: 1.3 SR Oct 19, 2006 - Added new readme Ver: 1.2 SR Oct 6, 2006 - Renamed ql-lun-state to ql-lun-state-online Ver: 1.1 SR June 23, 2006 - Added support for SLES 10 Ver: 1.0 SR May 17, 2006 - First release qla-tools-20140529/ql-set-cmd-timeout/000077500000000000000000000000001240021350500173175ustar00rootroot00000000000000qla-tools-20140529/ql-set-cmd-timeout/COPYING000066400000000000000000000431061240021350500203560ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. qla-tools-20140529/ql-set-cmd-timeout/README.ql-set-cmd-timeout.txt000066400000000000000000000221041240021350500244450ustar00rootroot00000000000000 Set Device Command Timeout Utility for Linux Readme QLogic Corporation. All rights reserved. Table of Contents 1. Package Contents 2. Requirements 3. OS Support 4. Supported Features 5. Using the Set Device Command Timeout Utility 5.1 Starting the Utility 5.2 Command Line Options 5.3 Menu Options 6. Additional Notes 7. Known Issues and Workarounds 8. Contacting Support 1. Package Contents The Set Device Command Timeout Utility package contains the following: * COPYING - GNU General Public License that describes user rights to copy, distribute, and use the open source content in this Linux tool. * ql-set-cmd-timeout.sh - Script file used to set the timeout on the devices connected to the QLogic FC adapter. * README.ql-set-cmd-timeout.txt - This readme file. * revision.qlsetcmdtimeout.txt - Text file that identifies the changes made between versions of this package. 2. Requirements The Set Device Command Timeout Utility (ql-set-cmd-timeout) requires one of the Linux platforms listed in section 3, OS Support. 3. OS Support The ql-set-cmd-timeout utility runs on the following OS platforms: * Red Hat RHEL AS 4.0 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 * Red Hat RHEL AS 5.0 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 * Novell SLES 9 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 * Novell SLES 10 (32-bit, 64-bit) on Intel IA64, Intel EM64T, AMD64 NOTE: For specific OS service packs (SP) and updates, refer to the descriptions where this software version is posted on the QLogic Web site: http://support.qlogic.com/support/drivers_software.aspx 4. Supported Features The ql-set-cmd-timeout utility: * Allows you to set the timeout on devices by specifying the host and target number using the command line. * Allows you to select a host to set timeout on targets connected to the host using a menu. * Sets a common value for all hosts at the same time. * Supports Fibre Channel driver version 8.xx.xx. 5. Using the Set Device Command Timeout Utility This utility allows you to set the timeout on the devices connected to the QLogic FC adapter. This timeout value applies to the commands sent to the device. This can help when target devices take longer to execute a command, for example under heavy I/O. Setting a longer timeout reduces the chance of the Linux SCSI mid-layer driver aborting the tasks after a timeout. The following sections describe how to use this utility: * 5.1 Starting the Utility * 5.2 Command Line Options * 5.3 Menu Options 5.1 Starting the Utility To start this utility, enter the following command: # ./ql-set-cmd-timeout.sh HOST TARGET TIMEOUT where: HOST is the QLogic adapter number. TARGET is the target connected to the adapter. TIMEOUT is the new timeout value to be set on the devices under TARGET. For example: For /sys/bus/pci/drivers/qla2300/0000:05:01.0/host2/target2:0:0/ HOST and TARGET will be HOST=2 (from ..host2..) TARGET=0 (from target2:0:0 <--) specify new timeout as # ./ql-set-cmd-timeout.sh 2 0 60 5.2 Command Line Options [DEFAULT] Displays the timeout on devices connected to the all HOSTs. These devices must be QLogic adapters. [HOST] Specifies the HOST value to see the timeout on devices connected to the HOST. These devices must be QLogic adapters. [HOST] [TARGET] Specifies the HOST and TARGET values to see the timeout on devices connected to the TARGET. These devices must be QLogic adapters. [HOST] [TARGET] [TIMEOUT] Specifies the HOST, TARGET, and TIMEOUT values to set the timeout on devices connected to the TARGET. These devices must be QLogic adapters. -h, --help, ? Displays the help text. -i, --interactive Invokes the menu-driven program. Examples: * To display the timeout of all devices connected to QLogic adapters, enter the following command: # ./ql-set-cmd-timeout.sh * To display the timeout of all devices connected to HOST 2, enter the following command: # ./ql-set-cmd-timeout.sh 2 * To display the timeout of devices connected on HOST 2, TARGET 0, enter the following command: # ./ql-set-cmd-timeout.sh 2 0 * To set a timeout of 30 seconds on HOST 2, TARGET 0, enter the following command: # ./ql-set-cmd-timeout.sh 2 0 30 * To invoke the menu, enter one of the following commands: # ./ql-set-cmd-timeout.sh -i # ./ql-set-cmd-timeout.sh --interactive * To view help, enter one of the following commands: # ./ql-set-cmd-timeout.sh -h # ./ql-set-cmd-timeout.sh --help 5.3 Menu Options The utility provides a menu-driven interface that provides finer control of the operation. To invoke the menu, use the -i or --interactive option with the ql-set-cmd-timeout utility command: # ./ql-set-cmd-timeout.sh -i Invoking this command opens the main menu. MAIN MENU 1. HOST2 2. HOST3 3. SELECT ALL HOSTS 4. SET COMMON TIMEOUT FOR ALL HOSTS 5. QUIT 1: HOST2 This option appears if the system has a QLogic adapter installed with a QLogic driver loaded. The host number differs from system to system; as an example, the host numbers 2 and 3 are shown here. Selecting the HOST by specifying the index number opens the next menu, where you can select a specific target. Select Target for HOST2 1. Target 0 2. Target 1 3. Target 2 4. Target 3 5. GO TO PREVIOUS MENU 6. Quit Please select one of the options above: 2 Select the TARGET by specifying the index number to open the next menu, where you can select a specific action. Select option: 1. MODIFY TIMEOUT 2. DISPLAY TIMEOUT 3. GO BACK TO PREVIOUS MENU 4. QUIT Please select one of the options above: 1 Please enter new timeout for selected device: 60 Modifying the devices...... DEVICE OLD TIMEOUT NEW TIMEOUT 2:0:0:0 4 60 2:0:0:4 4 60 2:0:0:5 4 60 2:0:0:6 4 60 Hit any key to continue...... Select the DISPLAY TIMEOUT option to display the following: Select option: 1. MODIFY TIMEOUT 2. DISPLAY TIMEOUT 3. GO BACK TO PREVIOUS MENU 4. QUIT Please select one of the options above: 2 DEVICE TIMEOUT 2:0:0:0 60 2:0:0:4 60 2:0:0:5 60 2:0:0:6 60 Hit any key to continue...... 2. SELECT ALL HOSTS Select this option to select targets on all the HOSTS, and then enter a timeout for each one. For example: MAIN MENU 1. HOST2 2. HOST3 3. SELECT ALL HOSTS 4. SET COMMON TIMEOUT FOR ALL HOSTS 5. QUIT Please select one of the options above: 3 Select the SELECT ALL HOSTS option by specifying the index number to open the next menu, where you can select a specific action. Select option: 1. MODIFY TIMEOUT 2. DISPLAY TIMEOUT 3. GO BACK TO PREVIOUS MENU 4. QUIT Please select one of the options above: 1 Enter new timeout for HOST 2 and TARGET 0: 40 Modifying the devices...... DEVICE OLD TIMEOUT NEW TIMEOUT 2:0:0:0 50 40 2:0:0:4 50 40 Enter new timeout for HOST 2 and TARGET 1: 5 Modifying the devices...... DEVICE OLD TIMEOUT NEW TIMEOUT 2:0:1:0 50 5 2:0:1:1 50 5 Select the DISPLAY TIMEOUT option to display the following. Select option: 1. MODIFY TIMEOUT 2. DISPLAY TIMEOUT 3. GO BACK TO PREVIOUS MENU 4. QUIT Please select one of the options above: 2 DEVICE OLD TIMEOUT NEW TIMEOUT 2:0:0:0 50 40 2:0:0:4 50 40 DEVICE OLD TIMEOUT NEW TIMEOUT 2:0:1:0 50 5 2:0:1:1 50 5 Hit any key to continue...... 3. SET COMMON TIMEOUT FOR ALL HOSTS Select this option to set the timeout on all the devices connected to all the targets on all QLogic adapters. 4. QUIT Exits the ql-set-cmd-timeout utility. 6. Additional Notes None 7. Known Issues and Workarounds None 8. Contacting Support Please feel free to contact your QLogic approved reseller or QLogic Technical Support at any phase of integration for assistance. QLogic Technical Support can be reached by the following methods: Web: http://support.qlogic.com E-mail: support@qlogic.com (c) Copyright 2009. All rights reserved worldwide. QLogic, the QLogic logo, and the Powered by QLogic logo are registered trademarks of QLogic Corporation. All other brand and product names are trademarks or registered trademarks of their respective owners. qla-tools-20140529/ql-set-cmd-timeout/ql-set-cmd-timeout.sh000077500000000000000000000601101240021350500233060ustar00rootroot00000000000000#!/bin/bash # QLogic FC HBA Set Device Timeout Utility # Copyright (C) 2006 QLogic Corporation (www.qlogic.com) # #This program is free software; you can redistribute it and/or modify #it under the terms of the GNU General Public License as published by #the Free Software Foundation; either version 2 of the License, or #(at your option) any later version. # #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. # #You should have received a copy of the GNU General Public License #along with this program; if not, write to the Free Software #Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #--------------------------------------------------------------------------# #This script is used to set the timeout on devices connected to QLogic HBAs #The timeout is applied to the commands sent to the target. This will be useful #where targets need longer time to execute a command during heavy I/O. #Setting a longer timeout can reduce the chances of Linux SCSI midlayer aborting #the tasks. #---------------------------------------------------------------------------# QL_SETTIMEOUT_VERSION=1.7 QL_SUCCESS=0 QL_FAIL=1 QL_CALL_AGAIN=2 QL_CALL_RETURNED=3 QL_CALL_AGAIN_NO_WAIT=4 QL_CALL_AGAIN_NO_WAIT1=5 QL_COMMON=0 QL_SETT_SCRIPT=$0 QL_MAX_TO=65536 QL_MIN_TO=0 ALL_HOSTS=() ALL_TARGETS=() #*****************************************# # qlu_hit_any_key() # Waits for user to hit a key # PARAMETERS : NONE # RETURNS : None #*****************************************# function qlu_hit_any_key() { echo -n "Hit any key to continue......" read -n 1 clear } #*****************************************# # qlu_is_number() # Check is input is a number or not # PARAMETERS : IN Values # RETURNS : 0: If number #*****************************************# function qlu_is_number() { echo $1 | grep -w "^[0-9]\+$" >& /dev/null return $? } #*****************************************# # qlu_display_usage() # Displays the short usage message # PARAMETERS : None # RETURNS : None #*****************************************# function qlu_display_usage() { echo "Usage: $QL_SETT_SCRIPT HOST TARGET TIMEOUT" echo "For more information please see help" echo "$QL_SETT_SCRIPT -h" exit 1 } # --------------------------------------------------------- # # echo_b() # # Prints messages in bold # # Parameter: # # $1 Message to be printed # # Returns: None. # # --------------------------------------------------------- # function echo_b() { echo -en "\033[1m${1}\033[0m" tput sgr0 } # --------------------------------------------------------- # # qlu_settimeout_help () # # Prints the help message # # Parameter: None # # Returns: None # # --------------------------------------------------------- # function qlu_settimeout_help() { clear echo "" echo_b "QLogic Linux Set Device Timeout Utility v$QL_SETTIMEOUT_VERSION" echo "" echo "" echo "Usage: ${QL_SETT_SCRIPT} [OPTIONS]" echo "" echo " [DEFAULT]" echo " Display timeout of devices connected to all HOSTs" echo "" echo " [HOST]" echo " Display timeout of devices connected to HOST" echo "" echo " [HOST] [TARGET]" echo " Display timeout of devices connected to a TARGET on HOST" echo "" echo " [HOST] [TARGET] [TIMEOUT]" echo " To set timeout on devices connected to a TARGET on HOST" echo "" echo " -h, --help, ?" echo " Prints this help message" echo "" echo " -i, --interactive" echo " Use this option to use the menu driven program" } #*****************************************# # modify_devices() # Changes the timeout of specified device # PARAMETERS : HOST TARGET AND TIMEOUT # RETURNS : NONE #*****************************************# function modify_devices () { local RET=1 local L_WC=0 local L_HOST=${1} local L_TARGET=${2} local L_TO=${3} echo "" while [ $RET -ne 0 ] do if [ ${L_TO} -ge ${QL_MIN_TO} ] && [ ${L_TO} -le ${QL_MAX_TO} ]; then get_luns ${L_HOST} ${L_TARGET} if [ $? -eq 0 ]; then #echo "No LUN for this host,target pair" return 1 else echo "Modifying the devices......" echo "" echo -e "DEVICE\t\t\t\tOLD TIMEOUT\t\tNEW TIMEOUT" QL_SORTED_LUNS=(`echo ${QL_LUNS[@]} | sed "s/ /\\n/g" | sort -n`) cd /sys/class/scsi_device for LUN in ${QL_SORTED_LUNS[@]} do cd ${L_HOST}\:0\:${L_TARGET}\:${LUN}/device echo_b "${L_HOST}:0:${L_TARGET}:${LUN}" L_WC=`echo ${L_HOST}:0:${L_TARGET}:${LUN} | wc -m` qlu_is_number $L_WC if [ $? -eq 0 ]; then if [ $L_WC -lt 9 ]; then echo -en "\t\t\t\t" elif [ $L_WC -lt 17 ]; then echo -en "\t\t\t" elif [ $L_WC -lt 25 ]; then echo -en "\t\t" else echo -en "\t" fi else echo -e "\t" fi echo -en "`cat timeout`" echo ${L_TO} > timeout echo -e "\t\t\t`cat timeout`" cd ../.. done | more RET=0 fi else while [ $RET -ne 0 ] do echo -en "Select new timeout in the range [$QL_MIN_TO - $QL_MAX_TO] : " read L_TO qlu_is_number $L_TO RET=$? if [ $RET -ne 0 ] ; then echo "Please enter a numeric value : " fi done RET=1 fi done } # --------------------------------------------------------- # # get_hosts () # # Detects all the targets connected to given host and fills # # ALL_TARGETS array # # Parameters : # # NONE # # Returns : # # Number of hosts # # --------------------------------------------------------- # function get_hosts { ls -d /sys/bus/pci/drivers/qla*/*/host* &> /dev/null if [ $? -eq 0 ]; then ALL_HOSTS=( `ls -d /sys/bus/pci/drivers/qla*/*/host* | sed -e "s/.*host//"` ) fi return ${#ALL_HOSTS[@]} } # --------------------------------------------------------- # # get_targets () # # Detects all the targets connected to given host and fills # # ALL_TARGETS array # # Parameters : # # HOST # # Returns : # # Number of targets # # --------------------------------------------------------- # function get_targets { local HOST=$1 local TARGET local TARGETS=() if [ -e /sys/class/scsi_host/host$HOST/device/ ]; then cd /sys/class/scsi_host/host$HOST/device/ ls -d rport-$HOST:0-* &> /dev/null if [ $? -eq 0 ]; then ALL_TARGETS=( `ls -d rport-$HOST:0-* | sed "s/rport-$HOST:0-//"` ) fi ls -d target$HOST:0:* &> /dev/null if [ $? -eq 0 ]; then ALL_TARGETS=( `ls -d target$HOST:0:* | sed "s/target$HOST:0://"` ) fi ls -d $HOST:0:* &> /dev/null if [ $? -eq 0 ]; then TARGETS=`ls -d $HOST:0:* | sed "s/$HOST:0:\(.*\):.*/\1/"` for TARGET in $TARGETS do echo "${ALL_TARGETS[@]}" | grep -w $TARGET >& /dev/null if [ $? -ne 0 ]; then ALL_TARGETS=(${ALL_TARGETS[@]} $TARGET) fi done fi fi return ${#ALL_TARGETS[@]} } # --------------------------------------------------------- # # get_luns () # # Detects all the LUNS connected to given TARGET and fills # # QL_LUNS array # # Parameters : # # # # Returns : # # Number of LUNS # # --------------------------------------------------------- # function get_luns { local HOST=${1} local TARGET=${2} if [ -e /sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET} ]; then cd /sys/class/scsi_host/host$HOST/device/target${HOST}:0:${TARGET}/ elif [ -e /sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET} ]; then cd /sys/class/scsi_host/host$HOST/device/rport-$HOST:0-$TARGET/target${HOST}:0:${TARGET}/ fi QL_LUNS=( `ls -d $HOST:0:$TARGET:* 2> /dev/null | sed "s/$HOST:0:$TARGET://"` ) return ${#QL_LUNS[@]} } #*****************************************# # display_timeout() # Displays the timeout of specified device # PARAMETERS : HOST & TARGET # RETURNS : NONE #*****************************************# function display_timeout { local L_WC local L_HOST=${1} local L_TARGET=${2} get_luns ${L_HOST} ${L_TARGET} if [ $? -eq 0 ]; then echo "No LUNS for HOST:$L_HOST TARGET:$L_TARGET " else echo "" echo -e "DEVICE\t\t\t\tTIMEOUT" QL_SORTED_LUNS=(`echo ${QL_LUNS[@]} | sed "s/ /\\n/g" | sort -n`) cd /sys/class/scsi_device for LUN in ${QL_SORTED_LUNS[@]} do cd ${L_HOST}\:0\:${L_TARGET}\:${LUN}/device echo_b "${L_HOST}:0:${L_TARGET}:${LUN}" L_WC=`echo ${L_HOST}:0:${L_TARGET}:${LUN} | wc -m` qlu_is_number $L_WC if [ $? -eq 0 ]; then if [ $L_WC -lt 9 ]; then echo -en "\t\t\t\t" elif [ $L_WC -lt 17 ]; then echo -en "\t\t\t" elif [ $L_WC -lt 25 ]; then echo -en "\t\t" else echo -en "\t" fi else echo -e "\t" fi echo -e "`cat timeout`" cd ../.. done | more fi } #*****************************************# # display_selective_dev() # Displays the timeout of specified device # PARAMETERS :NONE # RETURNS : NONE #*****************************************# function display_selective_dev { local L_WC local L_GO_BACK=0 local L_QUIT=0 local SEL_HOST local SEL_TARGET local SC2_CHOICE=0 local SC3_CHOICE=0 get_hosts STATUS=$QL_CALL_AGAIN # to adjust with while loop while [ $STATUS -eq $QL_CALL_AGAIN ] do clear LN=1 # Line number echo "Select HOST " for HOST in ${ALL_HOSTS[@]} do echo " $LN. Host $HOST" LN=$((LN+1)) done echo " $LN. GO BACK TO PREVIOUS MENU" L_GO_BACK=$LN LN=$((LN+1)) echo " $LN. QUIT" echo "" echo -n "Please select one of the options above : " read SC2_CHOICE # read user choice for qlu_screen_2 if [ "$SC1_CHOICE" == "" ]; then continue fi case $SC2_CHOICE in q | Q | quit | $LN ) exit 0 ;; esac if [ $SC2_CHOICE -ge 1 ] && [ $SC2_CHOICE -lt $LN ]; then STATUS=$QL_CALL_RETURNED fi done if [ $SC2_CHOICE -ne $L_GO_BACK ]; then SEL_HOST=${ALL_HOSTS[((${SC2_CHOICE} - 1))]} else return $QL_CALL_AGAIN_NO_WAIT fi STATUS=$QL_CALL_AGAIN # to adjust with while loop while [ $STATUS -eq $QL_CALL_AGAIN ] do clear LN=1 # Line number echo "Select Target for HOST${SEL_HOST}" get_targets ${SEL_HOST} for TARGETS in ${ALL_TARGETS[@]} do echo " $LN. Target $TARGETS" LN=$((LN+1)) done echo " $LN. GO BACK TO PREVIOUS MENU" L_GO_BACK=$LN LN=$((LN+1)) echo " $LN. QUIT" L_QUIT=$LN echo "" echo "Please select one of the options above : " read SC3_CHOICE # read user choice for qlu_screen_3 case $SC3_CHOICE in q | Q | quit | $L_QUIT ) exit 0 ;; esac if [ $SC3_CHOICE -ge 1 ] && [ $SC3_CHOICE -lt $LN ]; then STATUS=$QL_CALL_RETURNED fi done if [ $SC2_CHOICE -ne $L_GO_BACK ]; then SEL_TARGET=${ALL_TARGETS[((${SC3_CHOICE} - 1))]} else return $QL_CALL_AGAIN_NO_WAIT1 fi get_luns ${SEL_HOST} ${SEL_TARGET} if [ $? -eq 0 ]; then echo "No LUNS for HOST:$SEL_HOST TARGET:$SEL_TARGET " else echo "" echo -e "DEVICE\t\t\t\tTIMEOUT" QL_SORTED_LUNS=(`echo ${QL_LUNS[@]} | sed "s/ /\\n/g" | sort -n`) cd /sys/class/scsi_device for LUN in ${QL_SORTED_LUNS[@]} do cd ${SEL_HOST}\:0\:${SEL_TARGET}\:${LUN}/device echo_b "${SEL_HOST}:0:${SEL_TARGET}:${LUN}" L_WC=`echo ${SEL_HOST}:0:${SEL_TARGET}:${LUN} | wc -m` qlu_is_number $L_WC if [ $? -eq 0 ]; then if [ $L_WC -lt 9 ]; then echo -en "\t\t\t\t" elif [ $L_WC -lt 17 ]; then echo -en "\t\t\t" elif [ $L_WC -lt 25 ]; then echo -en "\t\t" else echo -en "\t" fi else echo -e "\t" fi echo -e "`cat timeout`" cd ../.. done fi return $QL_CALL_RETURNED } #*****************************************# # display_all() # # Display timeout of all devices, # # internally calls display_timeout # # PARAMETERS : HOST / ALL # # RETURNS : NONE # #*****************************************# function display_all() { local OPTION=${1} local HOST_LIST=() echo "${1}" | grep "^[0-9]" &> /dev/null if [ $? -eq 0 ]; then get_hosts echo "${ALL_HOSTS[@]}" | grep -w "${1}" &> /dev/null if [ $? -ne 0 ]; then echo "ERROR: HOST $1 not found on the system" exit 1 else HOST_LIST=($1) fi elif [ "$OPTION" == "ALL" ]; then get_hosts HOST_LIST=( `echo ${ALL_HOSTS[@]}` ) else exit 1 fi for HOST in ${HOST_LIST[@]} do get_targets $HOST if [ $? -eq 0 ]; then echo "No TARGET connected to HOST$HOST" else for TARGET in ${ALL_TARGETS[@]} do display_timeout $HOST $TARGET done fi done } #*****************************************# # all_devices() # Changes timeout of all devices, # internally calls modify_devices # PARAMETERS : TIMEOUT (if QL_COMMON =1) # else # NONE # RETURNS : NONE #*****************************************# function all_devices () { BACK=$QL_CALL_AGAIN # to adjust with while loop while [ $BACK -eq $QL_CALL_AGAIN ] do STATUS=$QL_CALL_AGAIN # to adjust with while loop while [ $STATUS -eq $QL_CALL_AGAIN ] do clear LN=1 # Line number echo "Select option: " echo " 1. MODIFY TIMEOUT" echo " 2. DISPLAY TIMEOUT" echo " 3. GO BACK TO PREVIOUS MENU" echo " 4. QUIT " echo "" echo -n "Please select one of the options above : " read SC2_CHOICE # read user choice for qlu_screen_2 case $SC2_CHOICE in q | Q | quit | 4 ) exit 0 ;; esac if [ $SC2_CHOICE -ge 1 ] && [ $SC2_CHOICE -lt 4 ]; then STATUS=$QL_CALL_RETURNED fi done if [ $SC2_CHOICE -ne 3 ]; then if [ $SC2_CHOICE -eq 1 ]; then modify_all_devices BACK=$QL_CALL_AGAIN qlu_hit_any_key else display_all ALL | more BACK=$QL_CALL_AGAIN qlu_hit_any_key fi else return $QL_CALL_AGAIN_NO_WAIT fi done return $QL_CALL_RETURNED } #*****************************************# # modify_all_devices() # Changes timeout of all devices, # internally calls modify_devices # PARAMETERS : TIMEOUT (if QL_COMMON =1) # else # NONE # RETURNS : NONE #*****************************************# function modify_all_devices () { local RET=1 # Clean ALL_TARGETS() first ALL_TARGETS=() cd /sys/class/scsi_device get_hosts for HOST in ${ALL_HOSTS[@]} do ls $HOST:0:*:*/device/timeout >& /dev/null if [ $? -eq 0 ]; then for TARGET in `ls -d $HOST:0:* 2> /dev/null | sed -e "s/$HOST:0://" | sed -e "s/:.*//"` do #echo " target value $TARGETS" echo ${ALL_TARGETS[@]} | grep "$TARGET\b" >& /dev/null if [ $? -ne 0 ]; then ALL_TARGETS=(${ALL_TARGETS[@]} $TARGET) fi done for TARGET in ${ALL_TARGETS[@]} do if [ $QL_COMMON -eq 0 ]; then while [ $RET -ne 0 ] do echo -n "Enter new timeout for HOST $HOST and TARGET $TARGET: " read N_TIMEOUT qlu_is_number $N_TIMEOUT RET=$? if [ $RET -ne 0 ]; then echo "Please enter a numeric value" fi done RET=1 else N_TIMEOUT=$1 fi modify_devices ${HOST} ${TARGET} ${N_TIMEOUT} done fi done } #*****************************************# # modify_sel_device () # Changes timeout of selected HOST # internally calls modify_devices # PARAMETERS : HOST # RETURNS : $QL_CALL_RETURNED #*****************************************# function modify_sel_device () { clear local SEL_HOST=$1 local SC2_CHOICE=0 local L_GO_BACK=0 local L_QUIT=0 local RET=1 cd /sys/class/scsi_device ls $SEL_HOST:0:*:*/device/timeout >& /dev/null if [ $? -ne 0 ]; then echo "No Targets connected to Host $SEL_HOST" return $QL_CALL_RETURNED fi for TARGETS in `ls -d $SEL_HOST:0:* | sed -e "s/$SEL_HOST:0://" | sed -e "s/:.*//"` do #echo " target value $TARGETS" echo ${ALL_TARGETS[@]} | grep "$TARGETS\b" >& /dev/null if [ $? -ne 0 ]; then ALL_TARGETS=(${ALL_TARGETS[@]} $TARGETS) fi done BACK=$QL_CALL_AGAIN while [ $BACK -eq $QL_CALL_AGAIN ] do STATUS=$QL_CALL_AGAIN # to adjust with while loop while [ $STATUS -eq $QL_CALL_AGAIN ] do clear LN=1 # Line number echo "Select Target for HOST${SEL_HOST}" for TARGETS in ${ALL_TARGETS[@]} do echo " $LN. Target $TARGETS" LN=$((LN+1)) done echo " $LN. GO BACK TO MAIN MENU" L_GO_BACK=$LN LN=$((LN+1)) echo " $LN. QUIT" L_QUIT=$LN echo "" echo -n "Please select one of the options above : " read SC2_CHOICE # read user choice for qlu_screen_2 case $SC2_CHOICE in q | Q | quit | $L_QUIT ) exit 0 ;; esac if [ $SC2_CHOICE -ge 1 ] && [ $SC2_CHOICE -lt $LN ]; then STATUS=$QL_CALL_RETURNED fi done if [ $SC2_CHOICE -ne $L_GO_BACK ]; then SEL_TARGET=${ALL_TARGETS[((${SC2_CHOICE} - 1))]} echo "" AGAIN=$QL_CALL_AGAIN # to adjust with while loop while [ $AGAIN -eq $QL_CALL_AGAIN ] do STATUS=$QL_CALL_AGAIN # to adjust with while loop while [ $STATUS -eq $QL_CALL_AGAIN ] do clear LN=1 # Line number echo "Select option: " echo " 1. MODIFY TIMEOUT" echo " 2. DISPLAY TIMEOUT" echo " 3. GO BACK TO PREVIOUS MENU" echo " 4. GO BACK TO MAIN MENU" echo " 5. QUIT " echo "" echo -n "Please select one of the options above : " read SC2_CHOICE # read user choice for qlu_screen_2 case $SC2_CHOICE in q | Q | quit | 5 ) exit 0 ;; esac if [ $SC2_CHOICE -ge 1 ] && [ $SC2_CHOICE -le 4 ]; then STATUS=$QL_CALL_RETURNED fi done if [ $SC2_CHOICE -eq 1 ]; then while [ $RET -ne 0 ] do echo -n "Please enter new timeout for selected device : " read N_TIMEOUT qlu_is_number $N_TIMEOUT RET=$? if [ $RET -ne 0 ]; then echo "Please enter a numeric value" fi done RET=1 modify_devices ${SEL_HOST} ${SEL_TARGET} ${N_TIMEOUT} AGAIN=$QL_CALL_AGAIN # to adjust with while loop qlu_hit_any_key fi if [ $SC2_CHOICE -eq 2 ]; then display_timeout ${SEL_HOST} ${SEL_TARGET} AGAIN=$QL_CALL_AGAIN # to adjust with while loop qlu_hit_any_key fi if [ $SC2_CHOICE -eq 3 ]; then AGAIN=$QL_CALL_RETURNED BACK=$QL_CALL_AGAIN fi if [ $SC2_CHOICE -eq 4 ]; then return $QL_CALL_AGAIN_NO_WAIT fi done else return $QL_CALL_AGAIN_NO_WAIT fi done return $QL_CALL_RETURNED } #*****************************************# # qlu_main_screen () # Displays the main screen of the program # Accepts and validates the input # PARAMETERS : NONE # RETURNS : $QL_CALL_AGAIN #*****************************************# function qlu_main_screen () { local RET=1 local HOST=0 local TARGET get_hosts STATUS=$QL_CALL_AGAIN # to adjust with while loop while [ $STATUS -eq $QL_CALL_AGAIN ] do clear echo_b " Welcome to QLogic Set Device Timeout Utility" echo "" echo "==============================================" echo "" echo "MAIN MENU" LN=1 # LN for Line Number for HOST in ${ALL_HOSTS[@]} do echo " $LN. HOST${HOST}" #1 LN=$((LN+1)) #2 done echo " $LN. SELECT ALL HOSTS" #2 echo " $((LN+1)). SET COMMON TIMEOUT FOR ALL HOSTS" #3 echo " $((LN+2)). QUIT" #4 echo "" echo -n "Please select one of the options above : " read SC1_CHOICE # read user choice for qlu_screen_2 TEMP=$((LN+2)) #4 case $SC1_CHOICE in q | Q | quit | $TEMP ) exit 0 ;; esac if [ $SC1_CHOICE -ge 1 ] && [ $SC1_CHOICE -le $((LN+2)) ]; then STATUS=$QL_CALL_RETURNED fi done TEMP=$((LN+1)) #3 #Choice 1 if [ $SC1_CHOICE -lt ${LN} ] && [ $SC1_CHOICE -gt 0 ]; then #0 /dev/null if [ $? -ne 0 ]; then echo "Host: $IN_HOST is not a QLogic HBA" exit 1 fi if [ $# -eq 3 ]; then get_targets ${IN_HOST} echo "${ALL_TARGETS[@]}" | grep "${IN_TARGET}\b" &> /dev/null if [ $? -ne 0 ]; then echo "Enter valid TARGET" qlu_display_usage exit 0 fi qlu_is_number ${IN_TIMEOUT} if [ $? -ne 0 ]; then echo "Input should be a number" qlu_display_usage else modify_devices ${IN_HOST} ${IN_TARGET} ${IN_TIMEOUT} exit 0 fi fi #here means user specified only HOST/TARGET if [ $# -eq 2 ]; then get_targets ${IN_HOST} echo "${ALL_TARGETS[@]}" | grep "${IN_TARGET}\b" &> /dev/null if [ $? -ne 0 ]; then echo "Enter valid TARGET" qlu_display_usage exit 0 fi display_timeout ${IN_HOST} ${IN_TARGET} exit 0 else display_all ${IN_HOST} | more fi ;; esac shift done else display_all ALL | more #qlu_display_usage fi qla-tools-20140529/ql-set-cmd-timeout/revision.qlsetcmdtimeout.txt000066400000000000000000000014071240021350500251420ustar00rootroot00000000000000******************************************* QLogic Set Device Command Timeout Utility ******************************************* Ver: 1.8 SR May 12 2009 - New README Ver: 1.7 SR Mar 12 2009 - Dont exit; return from modify_devices Ver: 1.6 SR Feb 19 2008 - Fix incorrect targets displayed ( ER0000000058847 ) - Include new Readme Ver: 1.5 SV Mar 17 2007 - Corrected "GO-BACK TO PREVIOUS MENU" ( ER0000000052423 ) Ver: 1.4 SV Feb 12 2007 - Readme file name changed to README.ql-set-cmd-timeout.txt Ver: 1.3 SV Jan 6, 2007 - Added support to display timeout - Readme modified Ver: 1.2 SR Oct 19, 2006 - Added new Readme Ver: 1.1 SR Oct 06, 2006 - Renamed ql-set-timeout to ql-set-cmd-timeout Ver: 1.0 SR May 17, 2006 - First release