$ old_verify = 'f$verify(f$trnlnm("raid$config_verify"))' $!----------------------------------------------------------------------------- $! $! RAID$CONFIG.COM $! $! Determine the existence, membership, and status of all RAID arrays and $! sparesets on the system, and their member devices. $! $! Results are placed either into logical names in a specified logical name $! table (default is the /PROCESS table), or defined as DCL global symbols $! in the context of the executing process. $! $! The P1 parameter determines whether the results are placed into logical $! names or DCL global symbols. If P1 is blank or contains "GLOBAL_SYMBOLS", $! the results are placed into DCL symbols. If P1 contains "LOGICAL_NAMES", $! the results are placed into logical names. By default, the logical names $! are defined in the Process table, but if P2 contains "GROUP" or "SYSTEM", $! the logical names are placed instead into the Group or System tables. $! $! The following information is returned by the procedure: $! $! For arrays: $! $! RAID$CONFIG_ARRAY_COUNT Number of RAID arrays $! RAID$CONFIG_ARRAY_n_ID RAID array ID for each RAID array $! RAID$CONFIG_ARRAY_n_RAID_LEVEL RAID array RAID Level (0, 5, 0+1) $! RAID$CONFIG_ARRAY_n_STATE RAID array state (normal, reconstructing, etc.) $! RAID$CONFIG_ARRAY_n_VIRTUAL_DEVICE_LIST DPAn: device name(s) for partition(s) $! RAID$CONFIG_ARRAY_n_MEMBER_COUNT RAID array size (# of members) $! RAID$CONFIG_ARRAY_n_MEMBER_m_DEVICE_NAME Member device names $! RAID$CONFIG_ARRAY_n_MEMBER_m_STATE Member state (normal, missing...) $! In addition, for RAID 0+1 arrays: $! RAID$CONFIG_ARRAY_n_MEMBER_m_SHADOW_MEMBER_COUNT Shadow set depth $! RAID$CONFIG_ARRAY_n_MEMBER_m_SHADOW_MEMBER_s_DEVICE_NAME Device names $! RAID$CONFIG_ARRAY_n_MEMBER_m_SHADOW_MEMBER_s_STATE State of each: $! "ShadowMember", "FullCopying", or "MergeCopying" $! $! For sparesets: $! $! RAID$CONFIG_SPARESET_COUNT Number of sparesets $! RAID$CONFIG_SPARESET_n_ID Spareset ID for each spareset $! RAID$CONFIG_SPARESET_n_CHARACTERISTIC_SIZE Spareset characteristic size $! RAID$CONFIG_SPARESET_n_MEMBER_COUNT Spareset size (# of members) $! RAID$CONFIG_SPARESET_n_MEMBER_m_DEVICE_NAME Member device names $! RAID$CONFIG_SPARESET_n_MEMBER_m_STATE Member state (bound, etc.) $! $! There is also a timestamp logical name defined if the results are placed $! into logical names: $! $! RAID$CONFIG_TIMESTAMP Time of data-gathering $! $! V2.2-001 $! Author: $! Keith B. Parris, Digital Equipment Corporation, 12/94 $! Internet: keith.parris@cxo.mts.dec.com or parris@eisner.decus.org $! $!----------------------------------------------------------------------------- $ old_mess = f$environment("MESSAGE") $ on control_y then goto SET_MESSAGE_BACK !In case they abort us $! The contents of the P1 parameter determine whether to place results in $! logical names or in DCL global symbols. $ USE_LOGICAL_NAMES := FALSE $! IF P1 .EQS. "" .OR. P1 .EQS. "GLOBAL_SYMBOLS" THEN - $!! USE_LOGICAL_NAMES := FALSE $ IF P1 .EQS. "LOGICAL_NAMES" THEN USE_LOGICAL_NAMES := TRUE $! Determine if results are to be placed into a logical name table or into $! global symbols. $ IF USE_LOGICAL_NAMES $ THEN !Define logical names $! The P2 parameter can be optionally included to specify the logical name $! table into which the results are to be placed: $ TABLE = "PROCESS" $ IF P2 .eqs. "SYSTEM" then TABLE = "SYSTEM" $!! IF P2 .eqs. "PROCESS" then TABLE = "PROCESS" $ IF P2 .eqs. "GROUP" then TABLE = "GROUP" $ DEFINE_IT := DEFINE/nolog/'TABLE' !Place in the specified table $ EQUALS = "" $ SHOW_IT = "!" !Disable output $! SHOW_IT := SHOW LOGICAL/GROUP !Uncomment for display output $ TIMESTAMP = F$TIME() !Record the time $ ELSE !Define global symbols $ DEFINE_IT = "" $ EQUALS = "==" $ SHOW_IT = "!" !Disable output $! SHOW_IT := SHOW SYMBOL/GLOBAL !Uncomment for display output $ ENDIF $!----------------------------------------------------------------------------- $! $! First, get information about the RAID arrays from RAID SHOW output $! $!----------------------------------------------------------------------------- $ pid = f$getjpi("","PID") $ TEMP_FILE_NAME := sys$scratch:RAID$CONFIG_RAID_SHOW_'pid'.LIST_TEMP $! Suppress the "No arrays found" error message $ set message/nofacility/noident/noseverity/notext $ RAID SHOW/OUTPUT='TEMP_FILE_NAME' $ set message'old_mess' $ CR = " " $ CR[0,8] = 13 !Carriage Return character $ ARRAY_COUNT = 0 $ CLOSE/NOLOG LIST $ OPEN/READ LIST 'TEMP_FILE_NAME' $ ARRAY_LOOP1: $ READ/END=ARRAY_EOF LIST REC $ IF F$LOCATE("Permanent RAID Array ID:",REC) .EQ. F$LENGTH(REC) THEN - GOTO ARRAY_LOOP1 $ ARRAY_COUNT = ARRAY_COUNT + 1 $ ID = F$EDIT(F$ELEMENT(1,":",REC),"TRIM") - CR $ 'DEFINE_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_ID 'EQUALS' "''ID'" $ 'SHOW_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_ID !!! $! $ ARRAY_LOOP2: $ READ/END=ARRAY_EOF LIST REC $ IF F$LOCATE("RAID Level:",REC) .EQ. F$LENGTH(REC) THEN - GOTO ARRAY_LOOP2 $ ARRAY_LEVEL = F$EDIT(F$ELEMENT(1,":",REC),"TRIM") - CR $ 'DEFINE_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_RAID_LEVEL - 'EQUALS' "''ARRAY_LEVEL'" $ 'SHOW_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_RAID_LEVEL !!! $! $ ARRAY_LOOP3: $ READ/END=ARRAY_EOF LIST REC $ IF F$LOCATE("Current State:",REC) .EQ. F$LENGTH(REC) THEN - GOTO ARRAY_LOOP3 $ ARRAY_STATE = F$EDIT(F$ELEMENT(1,":",REC),"TRIM") - CR $ 'DEFINE_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_STATE 'EQUALS' - "''ARRAY_STATE'" $ 'SHOW_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_STATE !!! $! $ ARRAY_LOOP4: $ READ/END=ARRAY_EOF LIST REC $ IF F$LOCATE("Index",REC) .EQ. F$LENGTH(REC) THEN GOTO ARRAY_LOOP4 $ IF F$LOCATE("Name",REC) .EQ. F$LENGTH(REC) THEN GOTO ARRAY_LOOP4 $ IF F$LOCATE("State",REC) .EQ. F$LENGTH(REC) THEN GOTO ARRAY_LOOP4 $! Grab the device name for each device which is an array member, and its state $ MEMBER_COUNT = 0 $ ARRAY_LOOP5: $ READ/END=ARRAY_END5 LIST REC $ REC = F$EDIT(REC,"COMPRESS,TRIM") - CR $ IF F$ELEMENT(0," ",REC) .EQS. "Virtual" THEN GOTO ARRAY_END5 $ INDEX = F$ELEMENT(0," ",REC) $ IF F$TYPE(INDEX) .NES. "INTEGER" THEN GOTO ARRAY_LOOP5 !Skip headings $ IF F$INTEGER(INDEX) .NE. MEMBER_COUNT THEN GOTO ARRAY_LOOP5 $ MEMBER_DEVICE = F$ELEMENT(1," ",REC) $ MEMBER_STATE = F$ELEMENT(2," ",REC) $ MEMBER_COUNT = MEMBER_COUNT + 1 $ 'DEFINE_IT' - RAID$CONFIG_ARRAY_'ARRAY_COUNT'_MEMBER_'MEMBER_COUNT'_DEVICE_NAME - 'EQUALS' "''MEMBER_DEVICE'" $ 'SHOW_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_MEMBER_'MEMBER_COUNT'_DEVICE_NAME !!! $ 'DEFINE_IT' - RAID$CONFIG_ARRAY_'ARRAY_COUNT'_MEMBER_'MEMBER_COUNT'_STATE - 'EQUALS' "''MEMBER_STATE'" $ 'SHOW_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_MEMBER_'MEMBER_COUNT'_STATE !!! $! $! Find the membership of each shadow set in RAID 0+1 arrays, and the status of $! each shadow set member. This information cannot be obtained from RAID SHOW, $! but is readily available using the DCL lexical function F$GETDVI(). $! $ if ARRAY_LEVEL .eqs. "0+1" $ then $! Get shadow set virtual unit name (_DSAn:) $ devname = MEMBER_DEVICE $ k = 0 $ LOOP_SHAD_MEM: !Get the device name of the next shadow set member $ devname = f$getdvi(devname,"SHDW_NEXT_MBR_NAME") $ if devname .eqs. "" then goto END_SHAD_MEM $ k = k + 1 $ 'DEFINE_IT' - RAID$CONFIG_ARRAY_'ARRAY_COUNT'_MEMBER_'MEMBER_COUNT'_SHADOW_MEMBER_'k'_DEVICE_NAME - 'EQUALS' "''devname'" $ 'SHOW_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_MEMBER_'MEMBER_COUNT'_SHADOW_MEMBER_'k'_DEVICE_NAME !!! $ shdw_mem_state = "Unknown" $ if f$getdvi(devname,"SHDW_MEMBER") then - shdw_mem_state = "ShadowMember" $ if f$getdvi(devname,"SHDW_CATCHUP_COPYING") then - shdw_mem_state = "FullCopying" $ if f$getdvi(devname,"SHDW_MERGE_COPYING") then - shdw_mem_state = "MergeCopying" $ 'DEFINE_IT' - RAID$CONFIG_ARRAY_'ARRAY_COUNT'_MEMBER_'MEMBER_COUNT'_SHADOW_MEMBER_'k'_STATE - 'EQUALS' "''shdw_mem_state'" $ 'SHOW_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_MEMBER_'MEMBER_COUNT'_SHADOW_MEMBER_'k'_STATE !!! $ goto LOOP_SHAD_MEM $ END_SHAD_MEM: $ 'DEFINE_IT' - RAID$CONFIG_ARRAY_'ARRAY_COUNT'_MEMBER_'MEMBER_COUNT'_SHADOW_MEMBER_COUNT 'EQUALS' 'k' $ 'SHOW_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_MEMBER_'MEMBER_COUNT'_SHADOW_MEMBER_COUNT !!! $ endif $! End of additional data-gathering for RAID 0+1 arrays $ GOTO ARRAY_LOOP5 $ ARRAY_END5: $! Grab the virtual device name for each partition for the array $ VIRTUAL_DEVICE_LIST = "" $ ARRAY_LOOP6: $ READ/END=ARRAY_END6 LIST REC $ REC = F$EDIT(REC,"COMPRESS,TRIM") $ IF F$EXTRACT(0,4,REC) .EQS. "Unit" THEN GOTO ARRAY_LOOP6 $ IF F$EXTRACT(0,4,REC) .EQS. "----" THEN GOTO ARRAY_LOOP6 $ IF F$EXTRACT(0,3,REC) .NES. "DPA" THEN GOTO ARRAY_END6 $ DEVICE = F$ELEMENT(0," ",REC) $ ARRAY_CLEANUP_NAME6: !Remove leading zeroes from unit number $ IF F$EXTRACT(3,1,DEVICE) .EQS. "0" .AND. F$LENGTH(DEVICE) .GT. 5 $ THEN $ DEVICE = "DPA" + F$EXTRACT(4,99,DEVICE) $ GOTO ARRAY_CLEANUP_NAME6 $ ENDIF $ VIRTUAL_DEVICE_LIST = VIRTUAL_DEVICE_LIST + "," + DEVICE $ GOTO ARRAY_LOOP6 $ ARRAY_END6: $ TEMP = VIRTUAL_DEVICE_LIST - "," $ 'DEFINE_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_VIRTUAL_DEVICE_LIST - 'EQUALS' "''TEMP'" $ 'SHOW_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_VIRTUAL_DEVICE_LIST !!! $ 'DEFINE_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_MEMBER_COUNT - 'EQUALS' 'MEMBER_COUNT' $ 'SHOW_IT' RAID$CONFIG_ARRAY_'ARRAY_COUNT'_MEMBER_COUNT !!! $ GOTO ARRAY_LOOP1 $ ARRAY_EOF: $ CLOSE LIST $ 'DEFINE_IT' RAID$CONFIG_ARRAY_COUNT 'EQUALS' 'ARRAY_COUNT' $ DELETE 'TEMP_FILE_NAME';*/NOLOG $ 'SHOW_IT' RAID$CONFIG_ARRAY_COUNT $ 'SHOW_IT' RAID$CONFIG_ARRAY* $!----------------------------------------------------------------------------- $! $! Now, obtain information about the sparesets from RAID SHOW/SPARESET output $! $!----------------------------------------------------------------------------- $ TEMP_FILE_NAME := sys$scratch:RAID$CONFIG_RAID_SHOW_SPARE_'pid'.LIST_TEMP $! Suppress the "No sparesets found" error message $ set message/nofacility/noident/noseverity/notext $ RAID SHOW/SPARESET/OUTPUT='TEMP_FILE_NAME' $ set message'old_mess' $ SPARESET_COUNT = 0 $ CLOSE/NOLOG LIST $ OPEN/READ LIST 'TEMP_FILE_NAME' $ SPARE_LOOP1: $ READ/END=SPARE_EOF LIST REC $ IF F$LOCATE("Spareset ID:",REC) .EQ. F$LENGTH(REC) THEN - GOTO SPARE_LOOP1 $ SPARESET_COUNT = SPARESET_COUNT + 1 $ TEMP = F$EDIT(F$ELEMENT(1,":",REC),"TRIM") - CR $ 'DEFINE_IT' RAID$CONFIG_SPARESET_'SPARESET_COUNT'_ID 'EQUALS' "''TEMP'" $ 'SHOW_IT' RAID$CONFIG_SPARESET_'SPARESET_COUNT'_ID !!! $! $ SPARE_LOOP2: $ READ/END=SPARE_EOF LIST REC $ IF F$LOCATE("Characteristic Size:",REC) .EQ. F$LENGTH(REC) THEN - GOTO SPARE_LOOP2 $ TEMP = F$EDIT(F$ELEMENT(1,":",REC),"TRIM") - CR $ 'DEFINE_IT' RAID$CONFIG_SPARESET_'SPARESET_COUNT'_CHARACTERISTIC_SIZE - 'EQUALS' "''TEMP'" $ 'SHOW_IT' RAID$CONFIG_SPARESET_'SPARESET_COUNT'_CHARACTERISTIC_SIZE !!! $! $ SPARE_LOOP4: $ READ/END=SPARE_EOF LIST REC $ IF F$LOCATE("Member",REC) .EQ. F$LENGTH(REC) THEN GOTO SPARE_LOOP4 $ IF F$LOCATE("Characteristic Size",REC) .EQ. F$LENGTH(REC) THEN GOTO SPARE_LOOP4 $ IF F$LOCATE("State",REC) .EQ. F$LENGTH(REC) THEN GOTO SPARE_LOOP4 $! Grab the device name for each device which is an array member, and its state $ MEMBER_COUNT = 0 $ SPARE_LOOP5: $ READ/END=SPARE_END5 LIST REC $ REC = F$EDIT(REC,"COMPRESS,TRIM") - CR $ IF REC .EQS. "Associated RAID Arrays" THEN GOTO SPARE_END5 $ MEMBER_DEVICE = F$ELEMENT(0," ",REC) $ IF F$LOCATE(":",MEMBER_DEVICE) .EQ. F$LENGTH(MEMBER_DEVICE) THEN - GOTO SPARE_LOOP5 $! CHAR_SIZE = F$ELEMENT(1," ",REC) $! IF F$TYPE(CHAR_SIZE) .NE. "INTEGER" THEN GOTO SPARE_LOOP5 $ MEMBER_STATE = F$ELEMENT(2," ",REC) $ MEMBER_COUNT = MEMBER_COUNT + 1 $ 'DEFINE_IT' - RAID$CONFIG_SPARESET_'SPARESET_COUNT'_MEMBER_'MEMBER_COUNT'_DEVICE_NAME - 'EQUALS' "''MEMBER_DEVICE'" $ 'SHOW_IT' RAID$CONFIG_SPARESET_'SPARESET_COUNT'_MEMBER_'MEMBER_COUNT'_DEVICE_NAME !!! $ 'DEFINE_IT' - RAID$CONFIG_SPARESET_'SPARESET_COUNT'_MEMBER_'MEMBER_COUNT'_STATE - 'EQUALS' "''MEMBER_STATE'" $ 'SHOW_IT' RAID$CONFIG_SPARESET_'SPARESET_COUNT'_MEMBER_'MEMBER_COUNT'_STATE !!! $ GOTO SPARE_LOOP5 $ SPARE_END5: $ 'DEFINE_IT' RAID$CONFIG_SPARESET_'SPARESET_COUNT'_MEMBER_COUNT - 'EQUALS' 'MEMBER_COUNT' $ 'SHOW_IT' RAID$CONFIG_SPARESET_'SPARESET_COUNT'_MEMBER_COUNT !!! $ GOTO SPARE_LOOP1 $ SPARE_EOF: $ CLOSE LIST $ 'DEFINE_IT' RAID$CONFIG_SPARESET_COUNT 'EQUALS' 'SPARESET_COUNT' $ 'SHOW_IT' RAID$CONFIG_SPARESET_COUNT $ 'SHOW_IT' RAID$CONFIG_SPARE* $ DELETE 'TEMP_FILE_NAME';*/NOLOG $ IF USE_LOGICAL_NAMES $ THEN !Define logical name for timestamp $ 'DEFINE_IT' RAID$CONFIG_TIMESTAMP 'EQUALS' "''TIMESTAMP'" $ ENDIF $ SET_MESSAGE_BACK: $ set message'old_mess' $ EXIT 1+0*f$verify(old_verify)