Home | History | Annotate | Download | only in cluster2dot
      1 #!/bin/ksh
      2 #
      3 # Version 1.1   20080707
      4 # Maintainer: Thorsten Frueauf
      5 #
      6 # CDDL HEADER START
      7 #
      8 # The contents of this file are subject to the terms of the
      9 # Common Development and Distribution License (the License).
     10 # You may not use this file except in compliance with the License.
     11 #
     12 # You can obtain a copy of the license at usr/src/CDDL.txt
     13 # or http://www.opensolaris.org/os/licensing.
     14 # See the License for the specific language governing permissions
     15 # and limitations under the License.
     16 #
     17 # When distributing Covered Code, include this CDDL HEADER in each
     18 # file and include the License file at <packagename>/CDDL.txt.
     19 # If applicable, add the following below this CDDL HEADER, with the
     20 # fields enclosed by brackets [] replaced with your own identifying
     21 # information: Portions Copyright [yyyy] [name of copyright owner]
     22 #
     23 # CDDL HEADER END
     24 #
     25 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     26 # Use is subject to license terms.
     27 #
     28 #
     29 # The script will create two files for further use:
     30 #    1) /tmp/${CLUSTERNAME}-resourcegroups.dot
     31 #    2) /tmp/${CLUSTERNAME}-resources.dot
     32 #
     33 # Both files can then be used as input files for the dot command within the
     34 # graphviz tools (http://www.graphviz.org/), e.g.
     35 #
     36 #    $ dot -Tps /tmp/${CLUSTERNAME}-resources.dot -o ${CLUSTERNAME}-resources.ps
     37 #
     38 # to create a postscript file to visualize the dependencies.
     39 #
     40 # 1) is creating a directed graph for resource group dependencies and
     41 #    affinities.
     42 #
     43 #    - black solid arrow   = RG dependency
     44 #    - green solid arrow   = strong positive affinity with failover delegation
     45 #    - blue solid arrow    = strong positive affinity
     46 #    - brown dotted arrow  = weak positive affinity
     47 #    - red solid arrow     = strong negative affinity
     48 #    - orange dotted arrow = weak negative affinity
     49 #
     50 # 2) is creating a directed graph for the various resource dependencies.
     51 #
     52 #    - black solid arrow   = resource dependency
     53 #    - black dotted arrow  = weak resource dependency
     54 #    - red solid arrow     = restart dependency
     55 #    - orange solid arrow  = offline restart dependencies
     56 #    - yellow solid arrow  = implicit dependency on network resources
     57 #
     58 
     59 PATH=/usr/cluster/bin:/bin:/usr/bin:/sbin:/usr/sbin
     60 
     61 if ! /usr/sbin/clinfo > /dev/null
     62 then
     63 	echo "System is not running in cluster mode."
     64 	exit 1
     65 fi
     66 
     67 if [ -f /usr/bin/zonename ]
     68 then
     69 	if [ "$(/usr/bin/zonename)" != "global" ]
     70 	then
     71 		echo "Script needs to be run in the global zone."
     72 		exit 1
     73 	fi
     74 fi
     75 
     76 CLUSTERNAME=`scha_cluster_get -O CLUSTERNAME` 
     77 
     78 OUTPUTRG="/tmp/${CLUSTERNAME}-resourcegroups.dot"
     79 OUTPUTRS="/tmp/${CLUSTERNAME}-resources.dot"
     80 OUTPUTTMP="/tmp/${CLUSTERNAME}-resources-tmp.dot"
     81 
     82 ALLRGS=`scha_cluster_get -O ALL_RESOURCEGROUPS`
     83 
     84 LOCALHOST=`uname -n`
     85 
     86 if [ -f ${OUTPUTRG} ]
     87 then
     88 	rm ${OUTPUTRG}
     89 fi
     90 
     91 if [ -f ${OUTPUTRS} ]
     92 then
     93 	rm ${OUTPUTRS}
     94 fi
     95 
     96 if [ -f ${OUTPUTTMP} ]
     97 then
     98 	rm ${OUTPUTTMP}
     99 fi
    100 
    101 echo "digraph \"${CLUSTERNAME}\" {" >> ${OUTPUTRG}
    102 echo "\tlabel=\"Cluster ${CLUSTERNAME} - RG Dependencies and Affinities\\\\n\\\\nblack solid arrow = RG dependency\\\\ngreen solid arrow = strong positive affinity with failover delegation\\\\nblue solid arrow = strong positive affinity\\\\nbrown dotted arrow = weak positive affinity\\\\nred solid arrow = strong negative affinity\\\\norange dotted arrow = weak negative affinity\";" >> ${OUTPUTRG}
    103 
    104 echo "digraph \"${CLUSTERNAME}\" {" >> ${OUTPUTRS}
    105 echo "\tlabel=\"Cluster ${CLUSTERNAME} - Resource Dependencies\\\\n\\\\nblack solid arrow = resource dependency\\\\nblack dotted arrow = weak resource dependency\\\\nred solid arrow = restart dependency\\\\norange solid arrow = offline restart dependencies\\\\nyellow solid arrow = implicit dependency on network resources\";" >> ${OUTPUTRS}
    106 
    107 for RG in ${ALLRGS}
    108 	do
    109 		if [ "x${RG}" = "x" ]; then
    110 			break
    111 		fi
    112 
    113 		echo "\tsubgraph \"cluster_${RG}\" {" >> ${OUTPUTRS}
    114 		echo "\t\tlabel=\"${RG}\";" >> ${OUTPUTRS}
    115 
    116 		RG_DEP=`scha_resourcegroup_get -O RG_DEPENDENCIES -G ${RG} | tr -s "\n" " "`
    117 		if [ "${RG_DEP}" != " " ]; then	 
    118 			for dep in ${RG_DEP}
    119 			do
    120 				echo "\t\"${RG}\" -> \"${dep}\" [shape=box];" >> ${OUTPUTRG}
    121 			done
    122 		else
    123 			echo "\t\"${RG}\" [shape=box];" >> ${OUTPUTRG}
    124 		fi
    125 
    126 		RG_AFF=`scha_resourcegroup_get -O RG_AFFINITIES -G ${RG} | tr -s "\n" " "`
    127 		if [ "${RG_AFF}" != " " ]; then	 
    128 			for dep in ${RG_AFF}
    129 			do
    130 				if echo ${dep} | grep "^+++" > /dev/null
    131 				then
    132 					echo "\t\"${RG}\" -> \"$(echo ${dep} | tr -d "^+++")\" [color=green,shape=box];" >> ${OUTPUTRG}
    133 					continue
    134 				fi
    135 
    136 				if echo ${dep} | grep "^++" > /dev/null
    137 				then
    138 					echo "\t\"${RG}\" -> \"$(echo ${dep} | tr -d "^++")\" [color=blue,shape=box];" >> ${OUTPUTRG}
    139 					continue
    140 				fi
    141 
    142 				if echo ${dep} | grep "^+" > /dev/null
    143 				then
    144 					echo "\t\"${RG}\" -> \"$(echo ${dep} | tr -d "^+")\" [color=brown,shape=box,style=dotted];" >> ${OUTPUTRG}
    145 					continue
    146 				fi
    147 
    148 				if echo ${dep} | grep "^--" > /dev/null
    149 				then
    150 					echo "\t\"${RG}\" -> \"$(echo ${dep} | tr -d "^--")\" [color=red,shape=box];" >> ${OUTPUTRG}
    151 					continue
    152 				fi
    153 
    154 				if echo ${dep} | grep "^-" > /dev/null
    155 				then
    156 					echo "\t\"${RG}\" -> \"$(echo ${dep} | tr -d "^-")\" [color=orange,shape=box,style=dotted];" >> ${OUTPUTRG}
    157 					continue
    158 				fi
    159 			done
    160 		fi
    161 
    162 		RESOURCES=`scha_resourcegroup_get -O RESOURCE_LIST -G ${RG}`
    163 		NONNETRS=
    164 		NETRS=
    165 
    166 		if [ "$(scha_resourcegroup_get -O Implicit_network_dependencies -G ${RG} | tr '[A-Z]' '[a-z]')" = "true" ]; then
    167 			IMPL_DEP=true
    168 			for RS in ${RESOURCES}
    169 			do
    170 				if echo $(scha_resource_get -O TYPE -R ${RS}) | /usr/xpg4/bin/grep -e ^SUNW.LogicalHostname -e ^SUNW.SharedAddress > /dev/null
    171 				then
    172 					if [ -z "${NETRS}" ]
    173 					then
    174 						NETRS=${RS}
    175 					else
    176 						NETRS="${NETRS} ${RS}"
    177 					fi
    178 				else
    179 					if [ -z "${NONNETRS}" ]
    180 					then
    181 						NONNETRS=${RS}
    182 					else
    183 						NONNETRS="${NONNETRS} ${RS}"
    184 					fi
    185 				fi
    186 			done
    187 		else
    188 			IMPL_DEP=false
    189 		fi
    190 
    191 		for RS in ${RESOURCES}
    192 			do
    193 				if [ "${IMPL_DEP}" = "true" -a ! -z "${NETRS}" ]
    194 				then
    195 					if echo ${NONNETRS} | tr -s " " "\n" | grep ^${RS}$ > /dev/null
    196 					then
    197 						for res in ${NETRS}
    198 						do
    199 							echo "\t\t\"${RS}\" -> \"${res}\" [color=yellow];" >> ${OUTPUTRS}
    200 						done
    201 					fi
    202 				fi
    203 
    204 				DEP=`scha_resource_get -O RESOURCE_DEPENDENCIES -R ${RS} | tr -s "\n" " "`
    205 				if [ "${DEP}" != " " ]; then
    206 					for dep in ${DEP}
    207 					do
    208 						if echo ${RESOURCES} | tr -s " " "\n" | grep -w ${dep} > /dev/null
    209 						then
    210 							echo "\t\t\"${RS}\" -> \"${dep}\";" >> ${OUTPUTRS}
    211 						else
    212 							echo "\t\"${RS}\" -> \"${dep}\";" >> ${OUTPUTTMP}
    213 						fi
    214 					done
    215 				else
    216 					echo "\t\t\"${RS}\";" >> ${OUTPUTRS}
    217 				fi
    218 
    219 				DEP_WEAK=`scha_resource_get -O RESOURCE_DEPENDENCIES_WEAK -R ${RS} | tr -s "\n" " "`
    220 				if [ "${DEP_WEAK}" != " " ]; then
    221 					for dep in ${DEP_WEAK}
    222 					do
    223 						if echo ${RESOURCES} | tr -s " " "\n" | grep -w ${dep} > /dev/null
    224 						then
    225 							echo "\t\t\"${RS}\" -> \"${dep}\" [style=dotted];" >> ${OUTPUTRS}
    226 						else
    227 							echo "\t\t\"${RS}\" -> \"${dep}\" [style=dotted];" >> ${OUTPUTTMP}
    228 						fi
    229 					done
    230 				else
    231 					echo "\t\t\"${RS}\";" >> ${OUTPUTRS}
    232 				fi
    233 
    234 				DEP_RESTART=`scha_resource_get -O RESOURCE_DEPENDENCIES_RESTART -R ${RS} | tr -s "\n" " "`
    235 				if [ "${DEP_RESTART}" != " " ]; then
    236 					for dep in ${DEP_RESTART}
    237 					do
    238 						if echo ${RESOURCES} | tr -s " " "\n" | grep -w ${dep} > /dev/null
    239 						then
    240 							echo "\t\t\"${RS}\" -> \"${dep}\" [color=red];" >> ${OUTPUTRS}
    241 						else
    242 							echo "\t\t\"${RS}\" -> \"${dep}\" [color=red];" >> ${OUTPUTTMP}
    243 						fi
    244 					done
    245 				else
    246 					echo "\t\t\"${RS}\";" >> ${OUTPUTRS}
    247 				fi
    248 
    249 				DEP_OFFLINE_RESTART=`scha_resource_get -O RESOURCE_DEPENDENCIES_OFFLINE_RESTART -R ${RS} | tr -s "\n" " "`
    250 				if [ "${DEP_OFFLINE_RESTART}" != " " ]; then
    251 					for dep in ${DEP_OFFLINE_RESTART}
    252 					do
    253 						if echo ${RESOURCES} | tr -s " " "\n" | grep -w ${dep} > /dev/null
    254 						then
    255 							echo "\t\t\"${RS}\" -> \"${dep}\" [color=orange];" >> ${OUTPUTRS}
    256 						else
    257 							echo "\t\t\"${RS}\" -> \"${dep}\" [color=orange];" >> ${OUTPUTTMP}
    258 						fi
    259 					done
    260 				else
    261 					echo "\t\t\"${RS}\";" >> ${OUTPUTRS}
    262 				fi
    263 
    264 		done
    265 		echo "\t}" >> ${OUTPUTRS}
    266 done
    267 
    268 if [ -f ${OUTPUTTMP} ]
    269 then
    270 	cat ${OUTPUTTMP} >> ${OUTPUTRS}
    271 fi
    272 
    273 echo "}" >> ${OUTPUTRS}
    274 echo "}" >> ${OUTPUTRG}
    275 
    276 echo "Output files for dot created:\n\t${OUTPUTRG}\n\t${OUTPUTRS}"
    277 exit 0
    278