运行结果如下:
$ ./nova-ifinfo a7026868-407c-4c54-bb8f-a68623d7e13f
vm name is: instance-00000035 # 查找VM的名字
qemu pid is: 43146, iface host fd: 28, iface fd: 26, iface MAC: fa:16:3e:3f:ae:50
# 查找VM的tap设备的fd,通过fd找到对应的bridge。
************************************************
VM:instance-00000035 ---> tap: tap4ab104d3-5f ---> bridge: qbr4ab104d3-5f
************************************************
# 遍历VM的bridge。
************************************************
bridge: qbr4ab104d3-5f
|__ qvb4ab104d3-5f
|__ tap4ab104d3-5f
************************************************
# 找到VM的bridge的veth设备,通过veth设备,找到对端接在哪个bridge上。
************************************************
bridge: qbr4ab104d3-5f bridge: br-int
|__ veth: qvb4ab104d3-5f <----> veth: qvo4ab104d3-5f __|
************************************************
# 接续查找该bridge接到了哪里。
************************************************
bridge: br-int bridge: br-tun
|__ veth: patch-tun <----> veth: patch-int __|
bridge: br-int bridge: br-ex
|__ veth: int-br-ex <----> veth: phy-br-ex __|
************************************************
内容如下:
$ cat nova-ifinfo
精简版
1 #!/bin/bash 2 ST=`nova hypervisor-servers $HOSTNAME | grep $1` 3 if [[ $? != 0 ]] ; then 4 echo "not find $1 on $HOSTNAME" 5 nova hypervisor-servers $HOSTNAME 6 exit 1 7 fi 8 9 ST=`nova show $1` 10 if [[ $? != 0 ]] ; then 11 nova list 12 exit 1 13 fi 14 15 QEMU_NAME=`nova show $1 |grep "OS-EXT-SRV-ATTR:instance_name" | awk '{print $4}'` 16 if [[ $? != 0 ]] ; then 17 exit 1 18 fi 19 20 ST=`sudo virsh domstate $1` 21 if [[ $? != 0 ]] ; then 22 exit 1 23 fi 24 if [[ "$ST" =~ "shut off" ]] ; then 25 sudo virsh list --all 26 echo "$QEMU_NAME is shut off" 27 exit 1 28 fi 29 echo "vm name is: $QEMU_NAME" 30 31 QEMU_CMD=`ps -ef |grep " $QEMU_NAME " |grep -v grep` 32 # echo $QEMU_CMD 33 QEMU_PID=`cut -d " " -f2 <<< $QEMU_CMD` 34 CMD_IFS="" 35 IF_FD="" 36 HOST_FD="" 37 [[ "$QEMU_CMD" =~ "-netdev" ]] && CMD_IFS=${QEMU_CMD#*-netdev} 38 [[ "$QEMU_CMD" =~ "tap,fd=" ]] && CMD_IFS=${CMD_IFS#*tap,fd=} && IF_FD=${CMD_IFS%%,*} 39 [[ "$QEMU_CMD" =~ "vhostfd=" ]] && CMD_IFS=${CMD_IFS#*vhostfd=} && HOST_FD=${CMD_IFS%% *} 40 [[ "$QEMU_CMD" =~ "mac=" ]] && CMD_MAC=${QEMU_CMD#*mac=} && CMD_MAC=${CMD_MAC%%,*} 41 42 echo "qemu pid is: $QEMU_PID, iface host fd: $HOST_FD, iface fd: $IF_FD, iface MAC: $CMD_MAC" 43 44 # egrep -l iff:.*tap* /proc/*/fdinfo/* 2>/dev/null|cut -d/ -f3 45 TAPNAME=`sudo cat /proc/$QEMU_PID/fdinfo/$IF_FD | grep "iff:.*tap*"` 46 TAPNAME=${TAPNAME#iff:[[:space:]]*} 47 # TAPNAME="${TAPNAME##[[:space:]]}" 48 # TAPNAME="${TAPNAME//[[:space:]]/}" 49 50 # kernel version less than 3.14 51 if [[ -z $TAPNAME ]]; then 52 TAPNAME=`ifconfig |grep ${CMD_MAC:2}` 53 TAPNAME="${TAPNAME%%[[:space:]]*}" 54 fi 55 56 BR=`ls -l /sys/class/net/$TAPNAME/brport/bridge` 57 BR=${BR##*/} 58 # BR="" 59 # for br in `ls /sys/class/net/`; do 60 # if [[ -d "/sys/class/net/$br/bridge" && -d "/sys/class/net/$br/lower_$TAPNAME" ]]; then 61 # BR=$br 62 # break 63 # fi 64 # done 65 66 echo "" 67 echo "************************************************" 68 echo "VM:$QEMU_NAME ---> tap: $TAPNAME ---> bridge: $BR" 69 echo "************************************************" 70 71 echo "" 72 echo "************************************************" 73 echo "bridge: $BR" 74 for port in `ls /sys/class/net/$BR/brif/`; do 75 echo " |__ $port" 76 done 77 echo "************************************************" 78 79 # BR_PORT="qvb${BR:3}" 80 # OVS_PORT="qvo${BR_PORT:3}" 81 OVS_BR_INT="" 82 echo "" 83 echo "************************************************" 84 for port in `ls /sys/class/net/$BR/brif/`; do 85 PORT_TY=`ethtool -i $port | grep "driver:" |awk '{print $2}'` 86 if [[ $PORT_TY == "veth" ]] ; then 87 PEER_INDEX=`ethtool -S $port | grep "peer_ifindex:" |awk '{print $2}'` 88 for peer in `ls /sys/class/net/`; do 89 INDEX=`cat /sys/class/net/$peer/ifindex` 90 if [[ $PEER_INDEX == $INDEX ]]; then 91 if [[ -d /sys/class/net/$OVS_PORT/brport/bridge ]]; then 92 OVS_BR_INT=`ls /sys/class/net/$OVS_PORT/brport/bridge -l` 93 OVS_BR_INT=${OVS_BR_INT##*/} 94 else 95 OVS_BR_INT=`sudo ovs-vsctl port-to-br $peer` 96 # OVS_BR_INT=`sudo ovs-vsctl iface-to-br $peer` 97 fi 98 echo "bridge: $BR bridge: $OVS_BR_INT" 99 echo " |__ patch: $port <----> patch: $peer __|" 100 fi 101 done 102 fi 103 done 104 echo "************************************************" 105 106 IS_OVS=`sudo ovs-vsctl list-br | grep $OVS_BR_INT` 107 OVS_INFOS=`sudo ovs-vsctl show |tr "\n" " "` 108 ALL="" 109 110 echo "" 111 echo "************************************************" 112 while [[ "$OVS_INFOS" =~ "{peer=" ]] 113 do 114 PORT=${OVS_INFOS%%\}*} 115 PORT=${PORT%[[:space:]]*type*} 116 PORT=${PORT##*Interface} 117 PORT=`echo $PORT` 118 PEER=${OVS_INFOS#*\{peer=} 119 PEER=${PEER%%\}*} 120 OVS_INFOS=${OVS_INFOS#*\{peer=*\}} 121 if [[ ! "$ALL" =~ "$PORT" ]] 122 then 123 ALL="$ALL $PORT $PEER" 124 PEER_BR=`sudo ovs-vsctl iface-to-br $PORT` 125 BR=`sudo ovs-vsctl iface-to-br $PEER` 126 echo "bridge: $BR bridge: $PEER_BR" 127 echo " |__ veth: $PEER <----> veth: $PORT __|" 128 echo "" 129 else 130 continue 131 fi 132 done 133 echo "************************************************" 134 135 # for port in `sudo ovs-vsctl show |grep "options: {peer=" |cut -d "=" -f2` 136 # do 137 # port=${port%%\}*} 138 # THIS_BR=`sudo ovs-vsctl iface-to-br $port` 139 # if [[ $THIS_BR == $OVS_BR_INT ]]; then 140 # 141 # echo "bridge: $THIS_BR bridge: $PEER_BR" 142 # echo " |__ veth: $port <----> veth: $peer __|" 143 # 144 # fi 145 # done
1 #!/bin/bash 2 ST=`nova hypervisor-servers $HOSTNAME | grep $1` 3 if [[ $? != 0 ]] ; then 4 echo "not find $1 on $HOSTNAME" 5 nova hypervisor-servers $HOSTNAME 6 exit 1 7 fi 8 9 ST=`nova show $1` 10 if [[ $? != 0 ]] ; then 11 nova list 12 exit 1 13 fi 14 15 QEMU_NAME=`nova show $1 |grep "OS-EXT-SRV-ATTR:instance_name" | awk '{print $4}'` 16 if [[ $? != 0 ]] ; then 17 exit 1 18 fi 19 20 ST=`sudo virsh domstate $1` 21 if [[ $? != 0 ]] ; then 22 exit 1 23 fi 24 if [[ "$ST" =~ "shut off" ]] ; then 25 sudo virsh list --all 26 echo "$QEMU_NAME is shut off" 27 exit 1 28 fi 29 echo "" 30 echo "vm name is: $QEMU_NAME" 31 32 QEMU_CMD=`ps -ef |grep " $QEMU_NAME " |grep -v grep` 33 # echo $QEMU_CMD 34 QEMU_PID=`cut -d " " -f2 <<< $QEMU_CMD` 35 CMD_IFS="" 36 IF_FD="" 37 HOST_FD="" 38 [[ "$QEMU_CMD" =~ "-netdev" ]] && CMD_IFS=${QEMU_CMD#*-netdev} 39 [[ "$QEMU_CMD" =~ "tap,fd=" ]] && CMD_IFS=${CMD_IFS#*tap,fd=} && IF_FD=${CMD_IFS%%,*} 40 [[ "$QEMU_CMD" =~ "vhostfd=" ]] && CMD_IFS=${CMD_IFS#*vhostfd=} && HOST_FD=${CMD_IFS%% *} 41 [[ "$QEMU_CMD" =~ "mac=" ]] && CMD_MAC=${QEMU_CMD#*mac=} && CMD_MAC=${CMD_MAC%%,*} 42 43 echo "qemu pid is: $QEMU_PID, iface host fd: $HOST_FD, iface fd: $IF_FD, iface MAC: $CMD_MAC" 44 45 FLOATING_IP=`nova floating-ip-list |grep $1` 46 FIX_IP=`awk '{print $8}' <<< $FLOATING_IP` 47 FLOATING_IP=`awk '{print $4}' <<< $FLOATING_IP` 48 NETINFO=`nova show $1 |grep "network *|"` 49 NETINFO=="${NETINFO##network[[:space:]]*|}" 50 NET_NAME="${NETINFO%[[:space:]]*network*}" 51 NET_NAME="${NET_NAME#*[[:space:]]*}" 52 NET_ID=`nova network-show $NET_NAME |grep "| *id *|" |awk '{print $4}'` 53 echo " fix ip is: $FIX_IP, floating ip is: $FLOATING_IP" 54 echo "network id is: $NET_ID" 55 echo "and info please run: sudo ip netns exec qdhcp-$NET_ID" 56 # echo `cat /opt/stack/data/neutron/dhcp/$NET_ID/opts |grep "router"` 57 58 # egrep -l iff:.*tap* /proc/*/fdinfo/* 2>/dev/null|cut -d/ -f3 59 TAPNAME=`sudo cat /proc/$QEMU_PID/fdinfo/$IF_FD | grep "iff:.*tap*"` 60 TAPNAME=${TAPNAME#iff:[[:space:]]*} 61 # TAPNAME="${TAPNAME##[[:space:]]}" 62 # TAPNAME="${TAPNAME//[[:space:]]/}" 63 64 # kernel version less than 3.14 65 if [[ -z $TAPNAME ]]; then 66 TAPNAME=`ifconfig |grep ${CMD_MAC:2}` 67 TAPNAME="${TAPNAME%%[[:space:]]*}" 68 fi 69 70 BR=`ls -l /sys/class/net/$TAPNAME/brport/bridge` 71 BR=${BR##*/} 72 # BR="" 73 # for br in `ls /sys/class/net/`; do 74 # if [[ -d "/sys/class/net/$br/bridge" && -d "/sys/class/net/$br/lower_$TAPNAME" ]]; then 75 # BR=$br 76 # break 77 # fi 78 # done 79 80 echo "" 81 echo "================================================================================" 82 echo "The follow are L2 info:" 83 echo "************************************************" 84 echo "VM:$QEMU_NAME ---> tap: $TAPNAME ---> bridge: $BR" 85 echo "************************************************" 86 87 echo "" 88 echo "************************************************" 89 echo "bridge: $BR" 90 for port in `ls /sys/class/net/$BR/brif/`; do 91 echo " |__ port: $port" 92 done 93 echo "************************************************" 94 95 # BR_PORT="qvb${BR:3}" 96 # OVS_PORT="qvo${BR_PORT:3}" 97 function br_connetion_brs_by_veth() 98 { 99 echo "" 100 echo "************************************************" 101 OVS_BR_INT="" 102 BR=$1 103 for port in `ls /sys/class/net/$BR/brif/`; do 104 PORT_TY=`ethtool -i $port | grep "driver:" |awk '{print $2}'` 105 if [[ $PORT_TY == "veth" ]] ; then 106 PEER_INDEX=`ethtool -S $port | grep "peer_ifindex:" |awk '{print $2}'` 107 for peer in `ls /sys/class/net/`; do 108 INDEX=`cat /sys/class/net/$peer/ifindex` 109 BR_TYPE="linux_br" 110 if [[ $PEER_INDEX == $INDEX ]]; then 111 if [[ -d /sys/class/net/$OVS_PORT/brport/bridge ]]; then 112 BR_TYPE="linux_br" 113 OVS_BR_INT=`ls /sys/class/net/$OVS_PORT/brport/bridge -l` 114 OVS_BR_INT=${OVS_BR_INT##*/} 115 else 116 BR_TYPE="ovs_br" 117 OVS_BR_INT=`sudo ovs-vsctl port-to-br $peer` 118 # OVS_BR_INT=`sudo ovs-vsctl iface-to-br $peer` 119 fi 120 echo "bridge: $BR $BR_TYPE: $OVS_BR_INT" 121 echo " |__ veth: $port <----> veth: $peer __|" 122 fi 123 done 124 fi 125 done 126 echo "************************************************" 127 } 128 br_connetion_brs_by_veth $BR 129 130 # IS_OVS=`sudo ovs-vsctl list-br | grep $OVS_BR_INT` 131 132 echo "" 133 echo "************************************************" 134 function connetion_between_brs_by_peer() 135 { 136 OVS_INFOS=`sudo ovs-vsctl show |tr "\n" " "` 137 ALL="" 138 while [[ "$OVS_INFOS" =~ "{peer=" ]] 139 do 140 PORT=${OVS_INFOS%%\}*} 141 PORT=${PORT%[[:space:]]*type*} 142 PORT=${PORT##*Interface} 143 PORT=`echo $PORT` 144 PEER=${OVS_INFOS#*\{peer=} 145 PEER=${PEER%%\}*} 146 OVS_INFOS=${OVS_INFOS#*\{peer=*\}} 147 if [[ ! "$ALL" =~ "$PORT" ]] 148 then 149 ALL="$ALL $PORT $PEER" 150 PEER_BR=`sudo ovs-vsctl iface-to-br $PORT` 151 BR=`sudo ovs-vsctl iface-to-br $PEER` 152 echo "ovs_br: $BR ovs_br: $PEER_BR" 153 echo " |__ patch: $PEER <----> patch: $PORT __|" 154 echo "" 155 else 156 continue 157 fi 158 done 159 } 160 connetion_between_brs_by_peer 161 echo "************************************************" 162 163 164 echo "" 165 echo "================================================================================" 166 echo "The follow are L3 info in namesapce:" 167 echo "" 168 echo "in name space qdhcp-$NET_ID:" 169 function ns_info() 170 { 171 NS=$1 172 LOCAL_IFS=`sudo ip netns exec $NS ip link |egrep "[0-9]+: " | awk '{print $2}'` 173 for i in $LOCAL_IFS 174 do 175 if [[ ${i%%:} == lo ]] 176 then 177 continue 178 fi 179 echo "interface: ${i%%:}" 180 sudo ip netns exec $NS ip a show ${i%%:} |grep "global ${i%%:}" 181 DVR=`sudo ip netns exec $NS ethtool -i ${i%%:}|grep "driver:" |awk '{print $2}'` 182 if [[ $DVR == "openvswitch" ]] 183 then 184 OVS_BR=`sudo ip netns exec $NS ovs-vsctl iface-to-br ${i%%:}` 185 echo "ovs-bridge: $OVS_BR" 186 echo " |__ port: ${i%%:}" 187 else 188 echo "unknow iface type $DVR" 189 fi 190 echo "" 191 done 192 return $((0+0)); 193 # return $($NS); 194 } 195 196 ns_info qdhcp-$NET_ID 197 echo "Get route info by:" 198 echo "sudo ip netns exec qdhcp-$NET_ID route" 199 echo "Get iptable info by:" 200 echo "sudo ip netns exec qdhcp-$NET_ID iptables -nv -t nat -L" 201 202 echo "" 203 echo "namespace router is: " 204 for i in `sudo ip netns |grep qrouter-` 205 do 206 echo "*****************************" 207 NAME_S=$i 208 ns_info $i 209 echo "Get route info by:" 210 echo "sudo ip netns exec $NAME_S route" 211 echo "Get iptable info by:" 212 echo "sudo ip netns exec $NAME_S iptables -nv -t nat -L" 213 echo "" 214 done 215 216 function filter_link_by_ip() 217 { 218 for i in `ip netns`; 219 do 220 L_IP=`sudo ip netns exec $i ip addr |grep $1`; 221 if [[ ! -z $L_IP ]]; then 222 L_PORT=${L_IP##*[[:space:]]} 223 echo "sudo ip netns exec $i ip a show $L_PORT" 224 sudo ip netns exec $i ip a show $L_PORT 225 break 226 fi 227 done 228 } 229 # filter_link_by_ip $FLOATING_IP 230 231 #something wrong with this logic 232 function ovs_br_2_ovs_br() 233 { 234 for port in `sudo ovs-vsctl show |grep "options: {peer=" |cut -d "=" -f1` 235 do 236 port=${port%%\}*} 237 echo $port 238 THIS_BR=`sudo ovs-vsctl iface-to-br $port` 239 if [[ $THIS_BR == $OVS_BR_INT ]]; then 240 241 echo "bridge: $THIS_BR bridge: $PEER_BR" 242 echo " |__ veth: $port <----> veth: $peer __|" 243 244 fi 245 done 246 } 247 248 # ovs_br_2_ovs_br 249 250 251 # we can use this logic to find which VM attach to br_int 252 function connetion_between_brs() 253 { 254 echo "" 255 echo "************************************************" 256 IS_OVS=`sudo ovs-vsctl list-br | grep $OVS_BR_INT` 257 if [[ $IS_OVS == $OVS_BR_INT ]]; then 258 for port in `sudo ovs-vsctl list-ifaces $OVS_BR_INT`; do 259 PORT_TY=`ethtool -i $port 2>&- | grep "driver:" |awk '{print $2}'` 260 if [[ $PORT_TY == "veth" ]] ; then 261 PEER_INDEX=`ethtool -S $port | grep "peer_ifindex:" |awk '{print $2}'` 262 for peer in `ls /sys/class/net/`; do 263 INDEX=`cat /sys/class/net/$peer/ifindex` 264 if [[ $PEER_INDEX == $INDEX ]]; then 265 PEER_INT="" 266 if [[ -d /sys/class/net/$peer/brport/bridge ]]; then 267 PEER_INT=`ls /sys/class/net/$peer/brport/bridge -l` 268 PEER_INT=${PEER_INT##*/} 269 else 270 PEER_INT=`sudo ovs-vsctl port-to-br $peer` 271 # PEER_INT=`sudo ovs-vsctl iface-to-br $peer` 272 fi 273 if [[ "x$PEER_INT" == "x" ]]; then 274 continue 275 fi 276 echo "bridge: $OVS_BR_INT bridge: $PEER_INT" 277 echo " |__ veth: $port <----> veth: $peer __|" 278 echo "" 279 fi 280 done 281 fi 282 done 283 fi 284 echo "************************************************" 285 } 286 # connetion_between_brs "br_int" 287 288 NETINFO=`nova show $1 |grep "network *|"` 289 function find_nova_net_id() 290 { 291 NETINFO=$1 292 NETINFO="${NETINFO##network[[:space:]]*|}" 293 NET_NAME="${NETINFO%[[:space:]]*network*}" 294 NET_NAME="${NET_NAME#*[[:space:]]*}" 295 ID=`nova network-show $NET_NAME |grep "| *id *|" |awk '{print $4}'` 296 echo "$ID" 297 } 298 NET_ID=`find_nova_net_id "$NETINFO"` 299 300 function find_nova_net_ips() 301 { 302 NETINFO=$1 303 IPS="${NETINFO#*network[[:space:]]*|}" 304 IPS="${IPS%[[:space:]]*|*}" 305 IPS="${IPS%[[:space:]]*}" 306 IPS=`tr "," " " <<< ${IPS#*[[:space:]]}` 307 for i in $IPS; do echo $i; done 308 } 309 # NET_ID=`find_nova_net_ips "$NETINFO"` 310 311 # ps ww `pgrep dnsmasq` |grep $NET_ID