tcpdump 패킷을 살펴보던중 내부의 로컬 vlan 패킷들이 새어 나오고 있는 걸 확인 했습니다. 그래서 flow 를 확인 했을때 아래와 같이 다 날아간 상태였습니다.
$ ovs-ofctl dump-flows br-int
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=7477.663s, table=0, n_packets=393227, n_bytes=137047120, idle_age=0, priority=0 actions=NORMAL
아래는 정상적인 플로우 세팅 상태입니다. 첫줄의 priority=3 과 같이 vlan exchange하는 구문이 존재합니다. dl_vlan=2001 actions=mod_vlan_vid:1
$ ovs-ofctl dump-flows br-int
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=0.475s, table=0, n_packets=69, n_bytes=4210, idle_age=0, priority=3,in_port=42,dl_vlan=2001 actions=mod_vlan_vid:1,NORMAL
cookie=0x0, duration=9.738s, table=0, n_packets=352, n_bytes=170403, idle_age=0, priority=2,in_port=42 actions=drop
cookie=0x0, duration=10.188s, table=0, n_packets=48, n_bytes=3288, idle_age=0, priority=1 actions=NORMAL
자세한걸 살펴보면 아래와 같이 4 crashes 와 같은 이름이 프로세스에 남아 있었고 core dumped 됐다는 기록이 있었습니다.
# ps -ef | grep ovs
root 22858 1 0 8월07 ? 03:28:01 ovs-vswitchd: monitoring pid 41425 (4 crashes: pid 22756 died, killed (Segmentation fault), core dumped)
root 41425 22858 0 12월06 ? 00:21:00 ovs-vswitchd unix:/var/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfile:info --mlockall --no-chdir --log-file=/var/log/openvswitch/ovs-vswitchd.log --pidfile=/var/run/openvswitch/ovs-vswitchd.pid --detach --monitor
그래서 이를 기반으로 /var/crash 에서 다행히 coredump 파일을 찾을 수 있었습니다. 코어덤프를 살펴봤을때 아래와 같은 스택을 보였습니다.
(gdb) bt
#0 0x0000000000459110 in ?? ()
#1 0x0000000000460253 in ?? ()
#2 0x0000000000460ab2 in ?? ()
#3 0x00000000004607b7 in ?? ()
#4 0x0000000000460da4 in ?? ()
#5 0x00000000004607b7 in ?? ()
#6 0x0000000000444ee3 in ?? ()
#7 0x00000000004451b9 in ?? ()
#8 0x0000000000445223 in ?? ()
#9 0x00000000004453ba in ?? ()
#10 0x000000000041b3a3 in ?? ()
#11 0x0000000000420e78 in ?? ()
#12 0x0000000000422ea2 in ?? ()
#13 0x0000000000424aaa in ?? ()
#14 0x00000000004250e6 in ?? ()
#15 0x000000000041228f in ?? ()
#16 0x00000000004081a5 in ?? ()
#17 0x00000000004059c5 in ?? ()
#18 0x00007f8e361ddec5 in __libc_start_main (main=0x405620, argc=11, argv=0x7fff3332c068, init=, fini=, rtld_fini=, stack_end=0x7fff3332c058) at libc-start.c:287
#19 0x0000000000405b19 in ?? ()
(저 주소의 값의 심볼을 확인하려면 https://launchpadlibrarian.net/181527666/Stacktrace.txt 에서 확인 가능합니다.)여기에서 심볼이 없는 상태라 우선 할수있는게 마땅히 없어서 #0의 0x459110 주소로 구글링 한 결과 아래의 값을 찾을 수 있었습니다.
https://bugs.launchpad.net/ubuntu/+source/openvswitch/+bug/1352570 이 버그에 대해서 살펴보면 다음과 같습니다.
ovs 1.11.0 ~ 2.0.0 사이에 아래와 같은 패치가 추가 됐습니다.
guarded-list: New data structure for thread-safe queue.
https://github.com/openvswitch/ovs/commit/8354bbc9ce36aec09b11ca5d55219c5c41c421ad
하지만 이 코드는 중간에 thread 에서 들고 있는 포인터를 지우는 버그를 발생시켰고
지우는 건 나중에 upcall 이후에 삭제할 수 있도록 아래 패치에서 해결 되었습니다.
이 패치는 2.0.2 2.1.0(2.1.3) 2.3.0 에 포함 되어 있습니다.
(ubuntu precise, trusty는 2.0.2가 최신입니다.)
ofproto-dpif: Complete all packet translations before freeing an ofproto.
https://github.com/openvswitch/ovs/commit/dd2e44f835fac8c2df99f84c54250c3ca981f2f5
(https://bugs.launchpad.net/ubuntu/+source/openvswitch/+bug/1352570)
아무튼 이 버그 때문에 갑자기 난데없이 플로우가 날라가는 버그가 발생되었습니다.
그렇다면 neutron에서는 왜 재생이 안되었는가를 확인 했을때 neutron 2014.1(icehouse)~ 2014.1.1 사이에 다음과 같은 패치가 추가된것을 확인 했습니다.
ovs가 리스타트 되서 플로우가 날아가더라도 neutron agent가 이를 감지해서 다시 플로우를 재생해 주는 코드입니다.
Reprogram flows when ovs-vswitchd restarts
https://github.com/openstack/neutron/commit/d00446be1739c93921e3b88763e05fc194ea9b2b
알고리즘은 다음과 같습니다.
br-int 에 22번 테이블 을 추가합니다.(canary table) 이 값은 이 플로우는 뉴트론에 의해서 생성된 것을 증명하기 위해 존재하는 값인것 같습니다. (만약에 ovs가 리스타트되면 이 canary flow or table이 없어지기 때문에 재생성 해야 함을 파악할 수 있습니다.)
이 값은 아래 같이 보입니다.
22번 table에 대해 flow가 보입니다.
$ ovs-ofctl dump-flows br-int table=22
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=211582.509s, table=22, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=0 actions=drop
전체 플로우에서는 이렇게 보입니다.
$ ovs-ofctl dump-flows br-int
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=215323.744s, table=0, n_packets=502600, n_bytes=56102074, idle_age=1, hard_age=65534, priority=3,in_port=16,dl_vlan=914 actions=mod_vlan_vid:1,NORMAL
cookie=0x0, duration=215324.53s, table=0, n_packets=607488, n_bytes=38955489, idle_age=1, hard_age=65534, priority=2,in_port=16 actions=drop
cookie=0x0, duration=215325.063s, table=0, n_packets=320576, n_bytes=25462363, idle_age=1, hard_age=65534, priority=1 actions=NORMAL
cookie=0x0, duration=215325.031s, table=22, n_packets=0, n_bytes=0, idle_age=65534, hard_age=65534, priority=0 actions=drop
아무튼 이패치를 하면 ovs가 날아가더라도 플로우를 재생할 수 있습니다.
다음으로는 이 패치와 함께 2014.1.1 ~ 2014.1.2 에 아래와 같은 패치도 관련되어 패치 됐습니다.
Default to setting secure mode on the integration bridge
https://github.com/openstack/neutron/commit/5e0ea72a4263a7604cb7ff44eca40a5bd0cffc8c
fail_mode가 secure의 의미는 아래와 같습니다.
$ man 5 ovs-vswitchd.conf.db
fail_mode: optional string, either secure or standalone
When a controller is configured, it is, ordinarily, responsible for setting up all flows on the switch. Thus, if the connection to the controller fails, no new network connections can be set up. If the connection to the controller stays down long enough, no packets can pass through the switch at all. This setting determines the switch’s response to such a situation. It may be set to one of the following:
standalone
If no message is received from the controller for three times the inactivity probe interval (see inactivity_probe), then Open vSwitch will take over responsibility for setting up flows. In this mode, Open vSwitch causes the bridge to act like an ordinary MAC-learning switch. Open vSwitch will continue to retry connecting to the controller in the background and, when the connection succeeds, it will discontinue its standalone behavior.
secure
Open vSwitch will not set up flows on its own when the controller connection fails or when no controllers are defined. The bridge will continue to retry connecting to any defined controllers forever.
The default is standalone if the value is unset, but future versions of Open vSwitch may change the default.
The standalone mode can create forwarding loops on a bridge that has more than one uplink port unless STP is enabled. To avoid loops on such a bridge, configure secure mode or enable STP(see stp_enable).
When more than one controller is configured, fail_mode is considered only when none of the configured controllers can be contacted.
Changing fail_mode when no primary controllers are configured clears the flow table.
추가로 ovs 2.3.0은 새로운 LTS 버전임으로 사용에 참고해야 할듯 합니다
http://openvswitch.org/pipermail/discuss/2014-August/014781.html
(추가로 2.3.1이 12/3에 릴리즈가..)
커널 참고
| Open vSwitch | Linux kernel
|:------------:|:-------------:
| 1.4.x | 2.6.18 to 3.2
| 1.5.x | 2.6.18 to 3.2
| 1.6.x | 2.6.18 to 3.2
| 1.7.x | 2.6.18 to 3.3
| 1.8.x | 2.6.18 to 3.4
| 1.9.x | 2.6.18 to 3.8
| 1.10.x | 2.6.18 to 3.8
| 1.11.x | 2.6.18 to 3.8
| 2.0.x | 2.6.32 to 3.10
| 2.1.x | 2.6.32 to 3.11
| 2.3.x | 2.6.32 to 3.14
ovs 관련 debug point를 잡으려면 아래글을 참고하시면 좋습니다.
http://roan.logdown.com/posts/238771-openvswitch-debug-enviroment
댓글 없음:
댓글 쓰기