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