Closed wdauchy closed 4 years ago
@wdauchy I think this is going to be a difficult one to track down.
SIGBUS is a strange signal to receive, especially on x86 architecture. Does the fault consistently occur at ipvswrapper.c: line 356?
I think the only way I have any hope of tracking this down is to have a copy of your full configuration. In terms of obfuscating it, could you please just change the first octet of each IPv4 address to 10, and change the first word of IPv6 addresses to fd00; this will mean that I won't have to go through the whole configuration replacing x
s with numbers.
It looks to me as though you have spun your own kernel. Are there any kernel configuration settings that you have changed?
Thank you for your answer.
@wdauchy I think this is going to be a difficult one to track down. SIGBUS is a strange signal to receive, especially on x86 architecture. Does the fault consistently occur at ipvswrapper.c: line 356?
yes I can also provide a core privately
I think the only way I have any hope of tracking this down is to have a copy of your full configuration. In terms of obfuscating it, could you please just change the first octet of each IPv4 address to 10, and change the first word of IPv6 addresses to fd00; this will mean that I won't have to go through the whole configuration replacing
x
s with numbers.
will send you that privately as github does not allow me to send it
It looks to me as though you have spun your own kernel. Are there any kernel configuration settings that you have changed?
yes we have our own build. also sent privately.
I think a copy of the core file would be helpful, along with the matching non-stripped keepalived executable (if you installed keepalived from rpms then the keepalived and keepalived-debug rpms would be fine).
@wdauchy The core dump that you have sent me is reporting that keepalived terminated due to signal 11, in function weigh_live_realservers, which doesn't match what you listed above:
[New LWP 8497]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `/usr/sbin/keepalived -D -m'.
Program terminated with signal 11, Segmentation fault.
#0 0x000056349a4449c0 in weigh_live_realservers (vs=0x56349b8af410) at ipwrapper.c:90
90 LIST_FOREACH(vs->rs, svr, e) {
Missing separate debuginfos, use: debuginfo-install keyutils-libs-1.5.8-3.el7.x86_64 krb5-libs-1.15.1-37.el7_7.2.x86_64 libcom_err-1.42.9-16.el7.x86_64 libselinux-2.5-14.1.el7.x86_64 pcre-8.32-17.el7.x86_64 pcre2-10.23-2.el7.x86_64 zlib-1.2.7-18.el7.x86_64
(gdb) bt
#0 0x000056349a4449c0 in weigh_live_realservers (vs=0x56349b8af410) at ipwrapper.c:90
#1 set_quorum_states () at ipwrapper.c:442
#2 0x000056349a43916b in validate_check_config () at check_data.c:1129
#3 0x000056349a435f13 in start_check (old_checkers_queue=0x0, prev_global_data=0x0) at check_daemon.c:306
#4 0x000056349a4364a7 in start_check_child () at check_daemon.c:657
#5 0x000056349a436630 in check_respawn_thread (thread=<optimized out>) at check_daemon.c:502
#6 0x000056349a44ffbb in thread_call (thread=0x56349b88de50) at scheduler.c:1776
#7 process_threads (m=0x56349b88ed30) at scheduler.c:1834
#8 0x000056349a450541 in launch_thread_scheduler (m=<optimized out>) at scheduler.c:1942
#9 0x000056349a4327ab in keepalived_main (argc=<optimized out>, argv=<optimized out>) at main.c:2220
#10 0x00007f6d92dad505 in __libc_start_main (main=0x56349a430c80 <main>, argc=3, argv=0x7ffdaaebc638, init=<optimized out>,
fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffdaaebc628) at ../csu/libc-start.c:266
#11 0x000056349a430cae in _start ()
I can certainly look at this, but it isn't the issue you reported.
wow I probably mixed them, let me double check that
there is probably another issue I did not saw with weigh_live_realservers
; I can open a new bug about it. in the meantime, I've sent you the core about ipvs_group_cmd
sorry for the confusion
@pqarmitage in fact we just realised removing "ip_family inet6" somehow workarounds the issue (but disable ipv6 in the context of mixed virtual server (ipv6 VIP + ipv4 RS)
The new core file looks better, many thanks.
For both the core files you have provided, it looks like a register has got a rather strange value. For the original problem, where the code is:
0x0000564d80bdb75e <+286>: je 0x564d80bdb798 <ipvs_cmd+344>
0x0000564d80bdb760 <+288>: cmp $0x482,%ebx
=> 0x0000564d80bdb766 <+294>: mov 0x10(%rbp),%r12
0x0000564d80bdb76a <+298>: jne 0x564d80bdb6f0 <ipvs_cmd+176>
0x0000564d80bdb76c <+300>: lea 0x224dc5(%rip),%rax # 0x564d80e00538
the registers are: rax 0xfffffffb 4294967291 rbx 0x482 1154 rcx 0x7f9da5a349f0 140315065534960 rdx 0x0 0 rsi 0x564d81bc9404 94890889090052 rdi 0x7ffe3d648e50 140729928420944 rbp 0x800000564d81bc8b 0x800000564d81bc8b rsp 0x7ffe3d648db0 0x7ffe3d648db0 r8 0x0 0 r9 0x7ffe3d648e1f 140729928420895 r10 0x3 3 r11 0x7f9da5b1da40 140315066489408 r12 0x564d81bc9340 94890889089856 r13 0x564d81bc9340 94890889089856 r14 0x0 0 r15 0x7ffe3d648e10 140729928420880 rip 0x564d80bdb766 0x564d80bdb766 <ipvs_cmd+294> eflags 0x10246 [ PF ZF IF RF ]
so data is around about 0x564d81bc0000. However, rbp is 0x800000564d81bc8b which rather looks as though the register has been shifted right 8 bits, and the MSB set; an alternative is that the register was restored from the stack with an offset of 1 byte from where it should have been.
In the problem in the original core dump (i.e. the one that didn't match the original issue report), the code is: 0x000056349a4449b8 <+56>: je 0x56349a4449df <set_quorum_states+95> 0x000056349a4449ba <+58>: nopw 0x0(%rax,%rax,1) => 0x000056349a4449c0 <+64>: mov 0x10(%rax),%rdx 0x000056349a4449c4 <+68>: cmpb $0x0,0xe4(%rdx) 0x000056349a4449cb <+75>: je 0x56349a4449d7 <set_quorum_states+87>
with data around 0x56349b000000 but rax is 0x56009b8b0180, so the 0x34 byte has been set to 0x00 (this is the least significant 8 bits of the most significant 32 bits).
Whilst I can remember Z80 assembler pretty well, I don't think I have ever gone beyond 80286 assembler on Intel, so it will take a bit of time to get the hang of x86_64 assembler, but I will try and follow this through to see if this really comes down to register corruption. I will also test your configuration on my Fedora 31 system, which has gcc 9.3.1 as opposed to gcc 9.2.1 which you appear to be using.
@pqarmitage have you check the mentioned scenario above? i.e ipv6 VIP + ipv4 RS it seems to be the root cause of our issues
@wdauchy You stated removing "ip_family inet6"
works around the issue; did you simply comment out the ip_family inet6
line, or completely remove the IPv6 virtual servers with IPv4 real servers?
we simply commented ip_family inet6 line.
That shouldn't make any difference. ip_family inet6
is only needed where the virtual server or virtual server group is specified by a fwmark and not all the virtual servers are IPv6. I will nevertheless have a look at this.
There are a number of configuration errors being logged. I think it would be helpful to resolve all of those first to see if that resolves the problem. Apart from there being no definition of $VS_COMMON_OPTIONS, which would most simply be resolved by adding a line at the top of the config file:
$VS_COMMON_OPTIONS=
The remaining errors I am seeing are:
Wed Apr 8 17:30:19 2020: (Line 390) Address family of virtual server and real server 10.236.136.20 don't match - skipping real server.
Wed Apr 8 17:30:19 2020: (Line 394) Address family of virtual server and real server 10.236.18.26 don't match - skipping real server.
Wed Apr 8 17:30:19 2020: (Line 409) Address family of virtual server and real server 10.236.136.20 don't match - skipping real server.
Wed Apr 8 17:30:19 2020: (Line 413) Address family of virtual server and real server 10.236.18.26 don't match - skipping real server.
Wed Apr 8 17:30:20 2020: (Line 723) Address family of virtual server and real server 10.236.100.20 don't match - skipping real server.
Wed Apr 8 17:30:20 2020: (Line 727) Address family of virtual server and real server 10.236.100.20 don't match - skipping real server.
Wed Apr 8 17:30:20 2020: (Line 3011) Address family of virtual server and real server 10.236.104.14 don't match - skipping real server.
Wed Apr 8 17:30:20 2020: (Line 3433) Address family of virtual server and real server 10.236.102.30 don't match - skipping real server.
Wed Apr 8 17:30:20 2020: (Line 3437) Address family of virtual server and real server 10.236.121.25 don't match - skipping real server.
Wed Apr 8 17:30:20 2020: (Line 3441) Address family of virtual server and real server 10.236.68.11 don't match - skipping real server.
Wed Apr 8 17:30:20 2020: (Line 3859) Address family of virtual server and real server 10.236.102.30 don't match - skipping real server.
Wed Apr 8 17:30:20 2020: (Line 3863) Address family of virtual server and real server 10.236.139.34 don't match - skipping real server.
Wed Apr 8 17:30:20 2020: (Line 3899) Address family of virtual server and real server 10.236.18.15 don't match - skipping real server.
Wed Apr 8 17:30:20 2020: (Line 4259) Address family of virtual server and real server 10.236.102.10 don't match - skipping real server.
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: Virtual server []:1 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: VS []:0: real server [10.236.100.20]:tcp:0 is duplicated - removing second rs
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Wed Apr 8 17:30:20 2020: Virtual server []:0 has no real servers - ignoring
Thanks for the precision, I noticed those errors and will have a deeper look at them in the following days. I however confirm the issue is gone after removing ip_family inet6 line (and defining VS_COMMON_OPTIONS) - but we can give another try after fixing them.
@wdauchy I can now reproduce the problem. As you say, removing the ip_family inet6
stops the problem occurring; defining VS_COMMON_OPTIONS does not make any difference.
I can now work on this and should be able to identify the problem. It looks as though keepalived's internal data structures are becoming corrupted.
Good news! (for the reproducer)
To summarise, so far there are three problems I have identified:
ip_family inet6
specifiedip_family inet6
is not specified, keepalived reports the address family does not match the virtual serverI will update this entry as we progress.
@pqarmitage (I'm working with @wdauchy)
Can a virtual_server_group have a mixture of IPv4 and IPv6 addresses if all the real servers are tunnelled?
This was our first intent. We switched to v4 + v6 dedicated vs_group when noticing that all v6 vips were discarded due to mixed families.
With this setup (v4 and v6 separated) the kernel is programmed (when checked using a decent ipvsadm version, entries are correct) but from what we understand the healthchecking part is going crazy.
We consequently thought about implementing this config first then discuss this feature with the community. Good to know that it's already identified with this issue ;)
@pierrecdn @wdauchy
Update
The problem is caused by the virtual servers where the virtual_server_group has IPv6 addresses, the real servers of the virtual server have IPv4 addresses, and the lvs_method is NAT. Changing the lvs_method to be TUN for these instances (i.e. at lines 382, 401, 715, 3003, 3425, 3851, 3891 and 4251 of your configuration) stops the problem occurring. Alternatively, removing the ip_family inet6
from those real servers and leaving the lvs_method as NAT also stops the problem occurring.
I have also resolved point 2 above, so that it will not be necessary to specify ip_family inet6
at all.
Now to identify what is causing the problem explained above.
Commit a4668f6 resolves the original issue reported.
Commit eb4a4b3 sets the address family from the virtual_server_group if all the real servers of a virtual server are tunnelled and the address family is not specified.
Commit eb4a4b3 means that you will no longer need to specify ip_family inet6
at all, but it would be good if you could test the updated code with your original configuration to ensure that it really is fixed for you.
I have also resolved point 2 above, so that it will not be necessary to specify ip_family inet6 at all.
That's pretty cool and fast!
Trying to give you more context to explain why one would use one IP family for RS instead of having everything dual-stacked and using only ip4-ip4 or ip6-ip6 (outer-inner scheme).
(As you probably guessed) our goal is to be able to transparently perform migrations of the internal infrastructure (RSes).
The first step for that is to support mixed VIP families for a VS (here mostly IPv4 and IPv6 VIPs forwarded to v4 RSes). Sounds achievable, hence our workaround to split VS and VS group per IP families, and the discovery of the current issue. Would be the same for v6 RSes.
Now let's imagine we have mixed families for a given RS pool, within a VS. The worst case being something like:
virtual_server_group my_vip {
198.51.100.1 80
198.51.100.1 443
2001:db8::1 80
2001:db8::1 443
}
virtual_server group my_vip {
# common stuff
lvs_method TUN type ipip
real_server 2001:db8::ff:1 {
weight 1
$HEALTHCHECK_DEFINITION
}
real_server 192.0.2.1 {
weight 1
$HEALTHCHECK_DEFINITION
}
}
e.g. by using correct modules on the RS (ipip + sit + ip6_tunnel for ip-ip based protocols, or ip_gre + ip6_gre for gre families), we can encapsulate using the appropriate address family, and let RS migrate to dual-stack or mono-stack ipv6 autonomously (thanks to an automation we have in place).
This is perfectly supported by ipvs:
$ sudo ipvsadm -Ln -t 198.51.100.1:443
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 198.51.100.1:443 mh
-> 192.0.2.1:443 Tunnel 1 0 0
-> [2001:db8::ff:1]:443 Tunnel 1 0 0
This would also mean for us the ability for keepalived to support it. I think it's worth creating a specific issue, what do you think?
@pierrecdn I do agree that creating a separate issue for allowing mixed IPv4/6 in a virtual server group should be a separate issue. Once you have confirmed that commit a4668f6 resolves your original issue I think this issue should be closed.
I will wait for you to create the new issue and add any thoughts about mixed IPv4/6 virtual server groups to that issue.
@pqarmitage I confirm the mentioned commits are fixing the segfault, thanks a lot for the quick fixes! I believe we can consider this issue as fixed and open a new one for the feature request.
@wdauchy @pierrecdn Commit fa1eaf7 should allow what you want to achieve with having both IPv4 and IPv6 addresses in a virtual server group. This is only permitted where all real and sorry servers of all virtual servers using the virtual server group and tunnelled, and also no fwmarks are configured on the virtual server group.
I will have a look later whether I can relax the restriction of not allowing fwmarks (it would mean that the fwmark configuration in the virtual server group would need to specify the address family for wach fwmark).
@pqarmitage so fast, I only had time to write the corresponding issue :smile_cat: :arrow_up: Testing this one as well.
Describe the bug
We are hitting a regular segfault on v2.0.20
To Reproduce
For now no clear reproducer, but the config below is hetting the segfault very regularly
Keepalived version
Distro
Details of any containerisation or hosted service
bare metal machine
Configuration file: A full copy of the configuration file, obfuscated if necessary to protect passwords and IP addresses