Hi Tim,
Op 24-4-2018 om 14:36 schreef Tim Düsterhus:
Hi
Am 23.04.2018 um 22:36 schrieb PiBa-NL:
Is there a bug in my script, or is it more likely that 'something' needs
fixing in the lua api / interaction?
I poked around a bit: The cause in this case is the Content-Length
header. It causes that haproxy does not use chunked encoding for the output.
My suspicion is some kind of "race condition". It looks like that the
applet function does not get scheduled any more, once all data is sent
over the wire and thus the output to stdout is not printed in all cases.
I could not reproduce the issue if I added another `applet:send()` below
the second print_r. I also could not reproduce the issue if the
Content-Length header specifies a length *greater* than the actual
length of the content. I could however reproduce it, if the
Content-Length header specifies a length *smaller* than the actual
length of the content.
Best regards
Tim Düsterhus
Thanks for investigating, i did a little more of my own also :) and got
some results (also a crash..).
As you say found i do string.len(response)+1 and then another send("1")
in the end it suddenly runs fine.
Running from gdb directly allowed me to get a readable backtrace of the
crash that seems to happen due to the print_r of the core.get_info() ..
Requesting the stats page from 1 and the coreinfo from 3 browserwindows.
When just requesting the core.get_info() and NOT printing it to
core.Info() it runs fine for a long time.
Somehow this output method seems related to some serous issue at least
when combined with large output from lua.. Perhaps there is a deeper
issue?.?
Technically its probably not advisable to dump such large output's on
the console.. But still to crash on that, i didn't expect it, and
dumping info on console is the only way i can easily 'debug' the scripts
interaction with haproxy..
Anyhow hoping it can be fixed or even maybe just some string can be
truncated at its maximum buffer length.?.
Regards,
PiBa-NL (Pieter)
global
nbthread 1
lua-load /root/haproxytest/print_r.lua
lua-load /root/haproxytest/smtpmailqueue/smtpmailqueue.lua
lua-load /root/haproxytest/serverhealthchecker/serverhealthchecker.lua
lua-load /root/haproxytest/serverhealth_smtpmail.lua
defaults
mode http
timeout connect 5s
timeout client 30s
timeout server 60s
frontend TestSite
bind *:80
acl webrequest path -m beg /webrequest
http-request use-service lua.testitweb-webrequest if webrequest
stats enable
stats admin if TRUE
stats refresh 1s
# prevent overloading yourself with loopback requests..
acl isloopback src 127.0.0.0/8
http-request deny if isloopback
default_backend myservers
backend myservers
server localSRVa 127.0.0.1:80 check
server localSRVb 127.0.0.1:81 check inter 20s
server localSRVc 127.0.0.1:82 check
##### serverhealth_smtpmail.lua ######
local smtpmailer = Smtpmailqueue("luamailer",5)
smtpmailer:setserver("127.0.0.1","25")
local checknotifier = function(subject, message, serverstatecounters,
allstates)
smtpmailer:addmail("haproxy@domain.local","itguy@domain.local","[srv-checker]"..subject,
message.."\r\n"..serverstatecounters.."\r\n\r\n"..allstates)
end
local mychecker = Serverhealthchecker("hapchecker",3,2,checknotifier)
testitweb = {}
testitweb.webrequest = function(applet)
if string.match(applet['path'],"/webrequest/mailstat") then
return smtpmailer:webstats(applet)
end
if string.match(applet['path'],"/webrequest/coreinfo") then
core.Info("################# CORE 1")
local cor = core.get_info()
print_r(cor)
core.Info("################# CORE 1 ^")
local resp = ""
print_r(core.get_info(),false,function(x)
resp=resp..string.gsub(x,"\n","<br/>")
end
)
response = "CoreInfo:"..resp
applet:add_header("Server", "haproxy/webstats")
applet:add_header("Content-Length", string.len(response))
applet:add_header("Content-Type", "text/html")
applet:add_header("Refresh", "1")
applet:start_response()
applet:send(response)
core.Info("################# CORE 2")
local cor = core.get_info()
print_r(cor)
core.Info("################# CORE 2 ^")
end
end
core.register_service("testitweb-webrequest", "http", testitweb.webrequest)
[info] 113/212806 (10702) : ################# CORE 1 ^
[info] 113/212806 (10702) : ################# CORE 2
(table) table: 0x8022d4900 [
"Memmax_MB": (number) 0
"Pid": (number) 10702
"Uptime_sec": (number) 9
"PipesUsed": (number) 0
"Uptime": (string) "0d 0h00m09s"
"SslFrontendMaxKeyRate": (number) 0
"CumConns": (number) 14
"PoolAlloc_MB": (number) 0
"SslFrontendKeyRate": (number) 0
"node": (string) "freebsd11"
"Idle_pct": (number) 100
"Run_queue": (number) 1
"ConnRate": (number) 1
"Maxpipes": (number) 0
"Nbproc": (number) 1
"CompressBpsOut": (number) 0
"Version": (string) "1.9-dev0-564d15-357"
"MaxSslConns": (number) 0
Program received signal SIGSEGV, Segmentation fault.
eb32sc_next_with_parent (start=0x0, scope=1) at eb32sctree.h:121
121 start = (eb_untag(start, EB_LEFT))->b[EB_RGHT];
Current language: auto; currently minimal
(gdb) bt full
#0 eb32sc_next_with_parent (start=0x0, scope=1) at eb32sctree.h:121
No locals.
#1 0x00000000005929d1 in eb32sc_next (eb32=0x80222b360, scope=1) at
eb32sctree.h:131
No locals.
#2 0x000000000059213e in process_runnable_tasks () at src/task.c:218
t = (struct task *) 0x80222b360
i = 32767
max_processed = 199
rq_next = (struct eb32sc_node *) 0x80222b360
local_tasks = 0x7fffffffe4f0
local_tasks_count = 0
final_tasks_count = 0
#3 0x0000000000510aab in run_poll_loop () at src/haproxy.c:2401
next = -115303713
exp = -115304019
#4 0x000000000050e3b0 in run_thread_poll_loop (data=0x802242088) at
src/haproxy.c:2463
start_lock = 0
ptif = (struct per_thread_init_fct *) 0x82a878
ptdf = (struct per_thread_deinit_fct *) 0x202
#5 0x000000000050afb9 in main (argc=3, argv=0x7fffffffea60) at
src/haproxy.c:3053
tids = (unsigned int *) 0x802242088
threads = (pthread_t *) 0x802242090
i = 1
err = 0
retry = 200
limit = {rlim_cur = 4014, rlim_max = 4014}
errmsg = 0x7fffffffe970 ""
pidfd = -1
(gdb)