]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
6 years agoMINOR: buffer: add a new buffer ring API to manipulate rings of buffers
Willy Tarreau [Fri, 24 May 2019 12:55:06 +0000 (14:55 +0200)] 
MINOR: buffer: add a new buffer ring API to manipulate rings of buffers

The purpose is to manipulate rings made of series of buffers so that
it is possible to continue to work on a next buffer once one is full.
This will be used by muxes to deal with contention between multiple
streams and a single output buffer. No data is expected to span over
multiple buffers, all of them will be used like a regular buffer. This
will significantly limit the amount of changes and the code complexity
while still supporting larger output buffering.

The ring is made of a head and a tail indexes both of which point to a
buffer descriptor. At least one descriptor is always valid, so it could
be seen as a form of pagination always presenting one buffer. The root
of the ring is itself stored into a buffer descriptor so that the user
only has to declare a buffer array and to call br_init() on it in order
to use it.

6 years agoMINOR: buffer: introduce b_make() to make a buffer from its parameters
Willy Tarreau [Fri, 24 May 2019 12:52:56 +0000 (14:52 +0200)] 
MINOR: buffer: introduce b_make() to make a buffer from its parameters

This is convenient to assign a buffer from parts of another one.

6 years agoCLEANUP: debug: remove the TRACE() macro
Willy Tarreau [Sun, 26 May 2019 07:25:59 +0000 (09:25 +0200)] 
CLEANUP: debug: remove the TRACE() macro

It has not been used for many years, is unlikely to be reused and
conflicts with the similarly named macro in flt_trace, causing warnings
at build time when including debug.h in low-level files. Let's simply
remove it.

6 years agoMEDIUM: mux-h2: avoid doing expensive buffer realigns when not absolutely needed
Willy Tarreau [Fri, 24 May 2019 17:42:18 +0000 (19:42 +0200)] 
MEDIUM: mux-h2: avoid doing expensive buffer realigns when not absolutely needed

Transferring large objects over H2 sometimes shows unexplained performance
variations. A long analysis resulted in the following discovery. Often the
mux buffer looks like this :

    [ empty_head |    data     | empty_tail ]

Typical numbers are (very common) :
  - empty_head = 31
  - empty_tail = 16  (total free=47)
  - data = 16337
  - size = 16384
  - data to copy: 43

The reason for these holes are the blocking factors that are not always
the same in and out (due to keeping 9 bytes for the frame size, or the
56 bytes corresponding to the HTX header). This can easily happen 10000
times a second if the network bandwidth permits it!

In this case, while copying a DATA frame we find that the buffer has its
free space wrapped so we decide to realign it to optimize the copy. It's
possible that this practice stems from the code used to emit headers,
which do not support fragmentation and which had no other option left.
But it comes with two problems :
  - we don't check if the data fits, which results in a memcpy for nothing
  - we can move huge amounts of data to just copy a small block.

This patch addresses this two ways :
  - first, by not forcing a data realignment if what we have to copy does
    not fit, as this is totally pointless ;

  - second, by refusing to move too large data blocks. The threshold was
    set to 1 kB, because it may make sense to move 1 kB of data to copy
    a 15 kB one at once, which will leave as a single 16 kB block, but
    it doesn't make sense to mvoe 15 kB to copy just 1 kB. In all cases
    the data would fit and would just be split into two blocks, which is
    not very expensive, hence the low limit to 1 kB

With such changes, realignments are very rare, they show up around once
every 15 seconds at 60 Gbps, and look like this, resulting in a much more
stable bit rate :

  buf=0x7fe6ec0c3510,h=16333,d=35,s=16384 room=16349 in=16337

This patch should be safe for backporting to 1.9 if some performance
issues are reported there.

6 years agoOPTIM: freq-ctr: don't take the date lock for most updates
Willy Tarreau [Sat, 25 May 2019 17:54:40 +0000 (19:54 +0200)] 
OPTIM: freq-ctr: don't take the date lock for most updates

It's amazing that the value was still incremented under the date lock,
let's first use an atomic increment for the counter and move it out of
the date lock to reduce contention. These are just counters, we don't
need to take locks if we're not rotating, atomic ops are enough. This
patch does this, and leaves the lock for when the period is over. It's
important to note that some values might be added just before or just
after a rotation but this is not a problem since we don't care if a
value is counted in the previous or next period when it's exactly on
the edge. Great care was taken to ensure that the current counter is
always atomically updated.

Other minor cleanups were performed, such as avoiding to reload the
value from memory after a CAS, or using &~1 instead of two shifts to
remove the lowest bit.

6 years agoBUG/MINOR: ssl_sock: Fix memory leak when disabling compression
Ilya Shipitsin [Fri, 24 May 2019 22:38:14 +0000 (03:38 +0500)] 
BUG/MINOR: ssl_sock: Fix memory leak when disabling compression

according to manpage:

       sk_TYPE_zero() sets the number of elements in sk to zero. It
       does not free sk so after this call sk is still valid.

so we need to free all elements

[wt: seems like it has been there forever and should be backported
 to all stable branches]

6 years agoDOC: fix typos
Michael Prokop [Fri, 24 May 2019 08:25:45 +0000 (10:25 +0200)] 
DOC: fix typos

s/accidently/accidentally/
s/any ot these messages/any of theses messages/
s/catched/caught/
s/completly/completely/
s/convertor/converter/
s/desribing/describing/
s/developper/developer/
s/eventhough/even though/
s/exectution/execution/
s/functionnality/functionality/
s/If it receive a/If it receives a/
s/In can even/It can even/
s/informations/information/
s/it will be remove /it will be removed /
s/langage/language/
s/mentionned/mentioned/
s/negociated/negotiated/
s/Optionnaly/Optionally/
s/ouputs/outputs/
s/outweights/outweighs/
s/ressources/resources/

6 years agoBUG/MINOR: htx: Remove a forgotten while loop in htx_defrag()
Christopher Faulet [Mon, 20 May 2019 07:32:25 +0000 (09:32 +0200)] 
BUG/MINOR: htx: Remove a forgotten while loop in htx_defrag()

Fortunately, this loop does nothing. Otherwise it would have led to an infinite
loop. It was probably forgotten during a refactoring, in the early stage of the
HTX.

This patch must be backported to 1.9.

6 years agoBUG/MEDIUM: proto-htx: Not forward too much data when 1xx reponses are handled
Christopher Faulet [Fri, 17 May 2019 07:58:45 +0000 (09:58 +0200)] 
BUG/MEDIUM: proto-htx: Not forward too much data when 1xx reponses are handled

When an 1xx reponse is processed, we forward it immediatly. But another message
may already be in the channel's buffer, waiting to be processed. This may be
another 1xx reponse or the final one. So instead of forwarding everything, we
must take care to only forward the processed 1xx response.

This patch must be backported to 1.9.

6 years agoBUG/MINOR: mux-h1: Report EOI instead EOS on parsing error or H2 upgrade
Christopher Faulet [Fri, 17 May 2019 07:14:10 +0000 (09:14 +0200)] 
BUG/MINOR: mux-h1: Report EOI instead EOS on parsing error or H2 upgrade

When a parsing error occurrs in the H1 multiplexer, we stop to copy HTX
blocks. So the error may be reported with an emtpy HTX message. For instance, if
the headers parsing failed. When it happens, the flag CS_FL_EOS is also set on
the conn_stream. But it is an error. Most of time, it is set on established
connections, so it is not really an issue. But if it happens when the server
connection is not fully established, the connection is shut down immediatly and
the stream-interface is switched from SI_ST_CON to SI_ST_DIS/CLO. So HTX
analyzers have no chance to catch the error.

Instead of setting CS_FL_EOS, it is fairly better to set CS_FL_EOI, which is the
right flag to use. The same is also done on H2 upgrade. As a side effet of this
fix, in the stream-interface code, we must now set the flag CF_READ_PARTIAL on
the channel when the flag CF_EOI is set. It is a warranty to wakeup the stream
when EOI is reported to the channel while no data are received.

This patch must be backported to 1.9.

6 years agoBUG/MINOR: mux-h2: Count EOM in bytes sent when a HEADERS frame is formatted
Christopher Faulet [Wed, 15 May 2019 12:22:48 +0000 (14:22 +0200)] 
BUG/MINOR: mux-h2: Count EOM in bytes sent when a HEADERS frame is formatted

In HTX, when a HEADERS frame is formatted before sending it to the client or the
server, If an EOM is found because there is no body, we must count it in the
number bytes sent.

This patch must be backported to 1.9.

6 years agoBUG/MINOR: lua: Set right direction and flags on new HTTP objects
Christopher Faulet [Thu, 23 May 2019 09:14:21 +0000 (11:14 +0200)] 
BUG/MINOR: lua: Set right direction and flags on new HTTP objects

When a LUA HTTP object is created using the current TXN object, it is important
to also set the right direction and flags, using ones from the TXN object.

This patch may be backported to all supported branches with the lua
support. But, it seems to have no impact for now.

6 years agoBUG/MEDIUM: spoe: Don't use the SPOE applet after releasing it
Christopher Faulet [Thu, 23 May 2019 20:47:48 +0000 (22:47 +0200)] 
BUG/MEDIUM: spoe: Don't use the SPOE applet after releasing it

In spoe_release_appctx(), the SPOE applet may be used after it was released to
get its exit status code. Of course, HAProxy crashes when this happens.

This patch must be backported to 1.9 and 1.8.

6 years agoBUG/MINOR: proto-htx: Try to keep connections alive on redirect
Christopher Faulet [Thu, 23 May 2019 14:44:59 +0000 (16:44 +0200)] 
BUG/MINOR: proto-htx: Try to keep connections alive on redirect

As fat as possible, we try to keep the connections alive on redirect. It's
possible when the request has no body or when the request parsing is finished.

No backport is needed.

6 years agoMINOR: stats: report the global output bit rate in human readable form
Willy Tarreau [Thu, 23 May 2019 10:23:55 +0000 (12:23 +0200)] 
MINOR: stats: report the global output bit rate in human readable form

The stats page now reports the per-process output bit rate and applies
the usual conversions needed to turn the TCP payload rate to an Ethernet
bit rate in order to give a reasonably accurate estimate of how far from
interface saturation we are.

6 years agoMINOR: raw_sock: report global traffic statistics
Willy Tarreau [Thu, 23 May 2019 09:39:14 +0000 (11:39 +0200)] 
MINOR: raw_sock: report global traffic statistics

Many times we've been missing per-process traffic statistics. While it
didn't make sense in multi-process mode, with threads it does. Thus we
now have a counter of bytes emitted by raw_sock, and a freq counter for
these as well. However, freq_ctr are limited to 32 bits, and given that
loads of 300 Gbps have already been reached over a loopback using
splicing, we need to downscale this a bit. Here we're storing 1/32 of
the byte rate, which gives a theorical limit of 128 GB/s or ~1 Tbps,
which is more than enough. Let's have fun re-reading this sentence in
2029 :-)  The values can be read in "show info" output on the CLI.

6 years agoBUILD: watchdog: condition it to USE_RT
Willy Tarreau [Thu, 23 May 2019 08:20:55 +0000 (10:20 +0200)] 
BUILD: watchdog: condition it to USE_RT

It's needed on Linux to have access to timerfd_*, and on FreeBSD this
lib is needed as well, though not enabled in our default build. We can
see later if it's OK to enable it, for now let's fix the build issues.

6 years agoBUILD: signals: FreeBSD has SI_LWP instead of SI_TKILL
Willy Tarreau [Thu, 23 May 2019 06:40:50 +0000 (08:40 +0200)] 
BUILD: signals: FreeBSD has SI_LWP instead of SI_TKILL

SI_TKILL is for Linux. We're again in the non-portable area. Both OSes
use macros to define these values so we can #ifdef them. Let's make
SI_TKILL defined based on SI_LWP when only the latter is defined.

6 years agoBUILD: watchdog: use si_value.sival_int, not si_int for the timer's value
Willy Tarreau [Thu, 23 May 2019 06:36:29 +0000 (08:36 +0200)] 
BUILD: watchdog: use si_value.sival_int, not si_int for the timer's value

Bah, the linux manpage suggests to use si_int but it's a fake, it's only
a define on sigval.sival_int where sigval is defined as si_value. Let's
use si_value.sival_int, at least it builds on both Linux and FreeBSD. It's
likely that this code will have to be limited to a small subset of OSes
if it causes difficulties like this.

6 years ago[RELEASE] Released version 2.0-dev4 v2.0-dev4
Willy Tarreau [Wed, 22 May 2019 18:48:33 +0000 (20:48 +0200)] 
[RELEASE] Released version 2.0-dev4

Released version 2.0-dev4 with the following main changes :
    - BUILD: enable freebsd builds on cirrus-ci
    - BUG/MINOR: http_fetch: Rely on the smp direction for "cookie()" and "hdr()"
    - MEDIUM: Make 'option forceclose' actually warn
    - MEDIUM: Make 'resolution_pool_size' directive fatal
    - DOC: management: place "show activity" at the right place
    - MINOR: cli/activity: show the dumping thread ID starting at 1
    - MINOR: task: export global_task_mask
    - MINOR: cli/debug: add a thread dump function
    - BUG/MEDIUM: streams: Don't use CF_EOI to decide if the request is complete.
    - BUG/MEDIUM: streams: Try to L7 retry before aborting the connection.
    - BUG/MINOR: debug: make ha_task_dump() always check the task before dumping it
    - BUG/MINOR: debug: make ha_task_dump() actually dump the requested task
    - MINOR: debug: make ha_thread_dump() and ha_task_dump() take a buffer
    - BUG/MINOR: debug: don't check the call date on tasklets
    - MINOR: thread: implement ha_thread_relax()
    - MINOR: task: put barriers after each write to curr_task
    - MINOR: task: always reset curr_task when freeing a task or tasklet
    - MINOR: stream: detach the stream from its own task on stream_free()
    - MEDIUM: debug/threads: implement an advanced thread dump system
    - REGTEST: extend the check duration on tls_health_checks and mark it slow
    - DOC: fix "successful" typo
    - MINOR: init: setenv HAPROXY_CFGFILES
    - MINOR: threads/init: synchronize the threads startup
    - MEDIUM: init/mworker: make the pipe register function a regular initcall
    - CLEANUP: memory: make the fault injection code use the OTHER_LOCK label
    - CLEANUP: threads: remove the now unused START_LOCK label
    - MINOR: init/threads: make the global threads an array of structs
    - MINOR: threads: add each thread's clockid into the global thread_info
    - CLEANUP: stream: remove an obsolete debugging test
    - MINOR: tools: add dump_hex()
    - MINOR: debug: implement ha_panic()
    - MINOR: debug/cli: add some debugging commands for developers
    - MINOR: tools: provide a may_access() function and make dump_hex() use it
    - MINOR: debug: make ha_panic() report threads starting at 1
    - REORG: compat: move some integer limit definitions from standard.h to compat.h
    - REORG: threads: move the struct thread_info from global.h to hathreads.h
    - MINOR: compat: make sure to always define clockid_t
    - MINOR: threads: always place the clockid in the struct thread_info
    - MINOR: threads: add a thread-local thread_info pointer "ti"
    - MINOR: time: move the cpu, mono, and idle time to thread_info
    - MINOR: time: add a function to retrieve another thread's cputime
    - MINOR: debug: report each thread's cpu usage in "show thread"
    - BUILD: threads: only assign the clock_id when supported
    - BUILD: makefile: use USE_OBSOLETE_LINKER for solaris
    - BUILD: makefile: remove -fomit-frame-pointer optimisation (solaris)
    - MAJOR: polling: add event ports support (Solaris)
    - BUG/MEDIUM: streams: Don't switch from SI_ST_CON to SI_ST_DIS on read0.
    - CLEANUP: time: refine the test on _POSIX_TIMERS
    - MINOR: compat: define a new empty type empty_t for non-implemented fields
    - CLEANUP: time: switch clockid_t to empty_t when not available
    - BUG/MINOR: mworker: Fix memory leak of mworker_proc members
    - CLEANUP: objtype: make obj_type() and obj_type_name() take consts
    - MINOR: debug: switch to SIGURG for thread dumps
    - CLEANUP: threads: really move thread_info to hathreads.c
    - MINOR: threads: make threads_{harmless|want_rdv}_mask constant 0 without threads
    - CLEANUP: debug: always report harmless/want_rdv even without threads
    - MINOR: threads: implement ha_tkill() and ha_tkillall()
    - CLEANUP: debug: make use of ha_tkill() and remove ifdefs
    - MINOR: stream: introduce a stream_dump() function and use it in stream_dump_and_crash()
    - MINOR: debug: dump streams when an applet, iocb or stream is known
    - MINOR: threads: add a "stuck" flag to the thread_info struct
    - MINOR: threads: add a timer_t per thread in thread_info
    - MAJOR: watchdog: implement a thread lockup detection mechanism
    - MINOR: stream: remove the cpu time detection from process_stream()
    - MINOR: connection: report the mux names in "haproxy -vv"
    - CLEANUP: mux-h1: use "H1" and not "h1" as the mux's name
    - BUG/MEDIUM: WURFL: segfault in wurfl-get() with missing info.
    - MINOR: WURFL: call header_retireve_callback() in dummy library
    - MINOR: WURFL: fixed Engine load failed error when wurfl-information-list contains wurfl_root_id
    - MINOR: WURFL: shows log messages during module initialization
    - MINOR: WURFL: removes heading wurfl-information-separator from wurfl-get-all() and wurfl-get() results
    - MINOR: WURFL: wurfl_get() and wurfl_get_all() now return an empty string if device detection fails
    - MEDIUM: WURFL: HTX awareness.
    - MINOR: WURFL: module version bump to 2.0
    - MINOR: WURFL: do not emit warnings when not configured
    - CONTRIB: wurfl: address 3 build issues in the wurfl dummy library
    - BUG/MEDIUM: init/threads: provide per-thread alloc/free function callbacks
    - BUILD: travis: add sanitizers to travis-ci builds
    - BUILD: time: remove the test on _POSIX_C_SOURCE
    - CLEANUP: build: rename some build macros to use the USE_* ones
    - CLEANUP: raw_sock: remove support for very old linux splice bug workaround
    - BUG/MEDIUM: dns: make the port numbers unsigned
    - MEDIUM: config: deprecate the antique req* and rsp* commands

6 years agoMEDIUM: config: deprecate the antique req* and rsp* commands
Willy Tarreau [Wed, 22 May 2019 18:34:35 +0000 (20:34 +0200)] 
MEDIUM: config: deprecate the antique req* and rsp* commands

These commands don't follow the same flow as the rest of the commands,
each of them iterates over all header lines before switching to the
next directive. In addition they make no distinction between start
line and headers and can lead to unparsable rewrites which are very
difficult to deal with internally.

Most of them are still occasionally found in configurations, mainly
because of the usual "we've always done this way". By marking them
deprecated and emitting a warning and recommendation on first use of
each of them, we will raise users' awareness of users regarding the
cleaner, faster and more reliable alternatives.

Some use cases of "reqrep" still appear from time to time for URL
rewriting that is not so convenient with other rules. But at least
users facing this requirement will explain their use case so that we
can best serve them. Some discussion started on this subject in a
thread linked to from github issue #100.

The goal is to remove them in 2.1 since they require to reparse the
result before indexing it and we don't want this hack to live long.
The following directives were marked deprecated :

  -reqadd
  -reqallow
  -reqdel
  -reqdeny
  -reqiallow
  -reqidel
  -reqideny
  -reqipass
  -reqirep
  -reqitarpit
  -reqpass
  -reqrep
  -reqtarpit
  -rspadd
  -rspdel
  -rspdeny
  -rspidel
  -rspideny
  -rspirep
  -rsprep

6 years agoBUG/MEDIUM: dns: make the port numbers unsigned
Willy Tarreau [Wed, 22 May 2019 18:07:45 +0000 (20:07 +0200)] 
BUG/MEDIUM: dns: make the port numbers unsigned

Mustafa Yildirim reported in Discourse that ports >32767 advertised
in SRV records are wrong. Given the high value they definitely
correspond to a sign extension of a negative number. The cause was
indeed that the port is declared as a signed int in the dns_answer_item
structure, and Lukas confirmed in github issue #103 that turning it to
unsigned addresses the issue.

It is worth noting that there are other such fields in this structure
that don't look right (ttl, priority, class, type) and that someone
should audit this part to be certain they are properly typed.

This fix must be backported to 1.9 and likely to 1.8 as well.

6 years agoCLEANUP: raw_sock: remove support for very old linux splice bug workaround
Willy Tarreau [Wed, 22 May 2019 17:55:24 +0000 (19:55 +0200)] 
CLEANUP: raw_sock: remove support for very old linux splice bug workaround

We've been dealing with a workaround for a bug in splice that used to
affect version 2.6.25 to 2.6.27.12 and which was fixed 10 years ago
in kernel versions which are not supported anymore. Given that people
who would use a kernel in such a range would face much more serious
stability and security issues, it's about time to get rid of this
workaround and of the ASSUME_SPLICE_WORKS build option used to disable
it.

6 years agoCLEANUP: build: rename some build macros to use the USE_* ones
Willy Tarreau [Wed, 22 May 2019 17:24:06 +0000 (19:24 +0200)] 
CLEANUP: build: rename some build macros to use the USE_* ones

We still have quite a number of build macros which are mapped 1:1 to a
USE_something setting in the makefile but which have a different name.
This patch cleans this up by renaming them to use the USE_something
one, allowing to clean up the makefile and make it more obvious when
reading the code what build option needs to be added.

The following renames were done :

 ENABLE_POLL -> USE_POLL
 ENABLE_EPOLL -> USE_EPOLL
 ENABLE_KQUEUE -> USE_KQUEUE
 ENABLE_EVPORTS -> USE_EVPORTS
 TPROXY -> USE_TPROXY
 NETFILTER -> USE_NETFILTER
 NEED_CRYPT_H -> USE_CRYPT_H
 CONFIG_HAP_CRYPT -> USE_LIBCRYPT
 CONFIG_HAP_NS -> DUSE_NS
 CONFIG_HAP_LINUX_SPLICE -> USE_LINUX_SPLICE
 CONFIG_HAP_LINUX_TPROXY -> USE_LINUX_TPROXY
 CONFIG_HAP_LINUX_VSYSCALL -> USE_LINUX_VSYSCALL

6 years agoBUILD: time: remove the test on _POSIX_C_SOURCE
Willy Tarreau [Wed, 22 May 2019 17:12:54 +0000 (19:12 +0200)] 
BUILD: time: remove the test on _POSIX_C_SOURCE

It seems it's not defined on FreeBSD while it's mentioned on Linux that
clock_gettime() can be detected using this. Given that we also have the
test for _POSIX_TIMERS>0 that should cover it well enough. If it breaks
on other systems, we'll see.

Report was here :
    https://github.com/haproxy/haproxy/runs/133866993

6 years agoBUILD: travis: add sanitizers to travis-ci builds
Ilya Shipitsin [Wed, 22 May 2019 15:12:15 +0000 (20:12 +0500)] 
BUILD: travis: add sanitizers to travis-ci builds

full list of changes:

use TARGET=osx instead of generic for osx builds,
add USE_PCRE_JIT=1, USE_GETADDRINFO=1 to build matrix,
enable address sanitizer for clang
enable device detection: WURFL, DEVICEATLAS

6 years agoBUG/MEDIUM: init/threads: provide per-thread alloc/free function callbacks
Willy Tarreau [Wed, 22 May 2019 12:42:12 +0000 (14:42 +0200)] 
BUG/MEDIUM: init/threads: provide per-thread alloc/free function callbacks

We currently have the ability to register functions to be called early
on thread creation and at thread deinitialization. It turns out this is
not sufficient because certain such functions may use resources that are
being allocated by the other ones, thus creating a race condition depending
only on the linking order. For example the mworker needs to register a
file descriptor while the pollers will reallocate the fd_updt[] array.
Similarly logs and trashes may be used by some init functions while it's
unclear whether they have been deduplicated.

The same issue happens on deinit, if the fd_updt[] or trash is released
before some functions finish to use them, we'll get into trouble.

This patch creates a couple of early and late callbacks for per-thread
allocation/freeing of resources. A few init functions were moved there,
and the fd init code was split between the two (since it used to both
allocate and initialize at once). This way the init/deinit sequence is
expected to be safe now.

This patch should be backported to 1.9 as at least the trash/log issue
seems to be present. The run_thread_poll_loop() code is a bit different
there as the mworker is not a callback, but it will have no effect and
it's enough to drop the mworker changes.

This bug was reported by Ilya Shipitsin in github issue #104.

6 years agoCONTRIB: wurfl: address 3 build issues in the wurfl dummy library
Willy Tarreau [Wed, 22 May 2019 12:54:27 +0000 (14:54 +0200)] 
CONTRIB: wurfl: address 3 build issues in the wurfl dummy library

Two of them were functions returning an string missing the return
statement and one is just the usual "set but not used".

6 years agoMINOR: WURFL: do not emit warnings when not configured
Willy Tarreau [Wed, 22 May 2019 12:01:22 +0000 (14:01 +0200)] 
MINOR: WURFL: do not emit warnings when not configured

At the moment the WURFL module emits 3 lines of warnings upon startup
when it is not referenced in the configuration file, which is quite
confusing. Let's make sure to keep it silent when not configured, as
detected by the absence of the wurfl-data-file statement.

6 years agoMINOR: WURFL: module version bump to 2.0
mbellomi [Tue, 21 May 2019 15:15:59 +0000 (17:15 +0200)] 
MINOR: WURFL: module version bump to 2.0

Make it version 2.0.

6 years agoMEDIUM: WURFL: HTX awareness.
mbellomi [Tue, 21 May 2019 15:15:07 +0000 (17:15 +0200)] 
MEDIUM: WURFL: HTX awareness.

Now wurfl fetch process is fully  HTX aware.

6 years agoMINOR: WURFL: wurfl_get() and wurfl_get_all() now return an empty string if device...
mbellomi [Tue, 21 May 2019 14:41:24 +0000 (16:41 +0200)] 
MINOR: WURFL: wurfl_get() and wurfl_get_all() now return an empty string if device detection fails

6 years agoMINOR: WURFL: removes heading wurfl-information-separator from wurfl-get-all() and...
mbellomi [Tue, 21 May 2019 14:29:22 +0000 (16:29 +0200)] 
MINOR: WURFL: removes heading wurfl-information-separator from wurfl-get-all() and wurfl-get() results

6 years agoMINOR: WURFL: shows log messages during module initialization
mbellomi [Tue, 21 May 2019 14:11:42 +0000 (16:11 +0200)] 
MINOR: WURFL: shows log messages during module initialization

Now some useful startup information is logged to stderr. Previously they
were lost because logs were not yet enabled.

6 years agoMINOR: WURFL: fixed Engine load failed error when wurfl-information-list contains...
mbellomi [Tue, 21 May 2019 13:51:46 +0000 (15:51 +0200)] 
MINOR: WURFL: fixed Engine load failed error when wurfl-information-list contains wurfl_root_id

6 years agoMINOR: WURFL: call header_retireve_callback() in dummy library
mbellomi [Tue, 21 May 2019 13:44:53 +0000 (15:44 +0200)] 
MINOR: WURFL: call header_retireve_callback() in dummy library

The current coverage of the dummy library was limited because the callbacks
passed to wurfl_lookup() were not called. Now we do call them with one existing
and one non-existing headers to make sure that ha_wurfl_retrieve_header() is
covered by the tests as well.

6 years agoBUG/MEDIUM: WURFL: segfault in wurfl-get() with missing info.
mbellomi [Tue, 21 May 2019 13:32:48 +0000 (15:32 +0200)] 
BUG/MEDIUM: WURFL: segfault in wurfl-get() with missing info.

A segfault may happen in ha_wurfl_get() when dereferencing information not
present in wurfl-information-list. Check the node retrieved from the tree,
not its container.

This fix must be backported to 1.9.

6 years agoCLEANUP: mux-h1: use "H1" and not "h1" as the mux's name
Willy Tarreau [Wed, 22 May 2019 09:36:54 +0000 (11:36 +0200)] 
CLEANUP: mux-h1: use "H1" and not "h1" as the mux's name

The mux's name is the only one reported in lower case in "show sess"
or "haproxy -vv" while the other ones are upper case, so it loses and
the other ones win :-)

6 years agoMINOR: connection: report the mux names in "haproxy -vv"
Willy Tarreau [Wed, 22 May 2019 09:44:03 +0000 (11:44 +0200)] 
MINOR: connection: report the mux names in "haproxy -vv"

Since the mux names appear at a few places (dumps etc), let's list
them in front of supported mux protocols in "haproxy -vv".

6 years agoMINOR: stream: remove the cpu time detection from process_stream()
Willy Tarreau [Wed, 22 May 2019 06:57:01 +0000 (08:57 +0200)] 
MINOR: stream: remove the cpu time detection from process_stream()

It was not as efficient as the watchdog in that it would only trigger
after the problem resolved by itself, and still required a huge margin
to make sure we didn't trigger for an invalid reason. This used to leave
little indication about the cause. Better use the watchdog now and
improve it if needed.

The detector of unkillable tasks remains active though.

6 years agoMAJOR: watchdog: implement a thread lockup detection mechanism
Willy Tarreau [Fri, 3 May 2019 11:52:18 +0000 (13:52 +0200)] 
MAJOR: watchdog: implement a thread lockup detection mechanism

Since threads were introduced, we've naturally had a number of bugs
related to locking issues. In addition we've also got some issues
with corrupted lists in certain rare cases not necessarily involving
threads. Not only these events cause a lot of trouble to the production
as it is very hard to detect that the process is stuck in a loop and
doesn't deliver the service anymore, but it's often difficult (or too
late) to collect more debugging information.

The patch presented here implements a lockup detection mechanism, also
known as "watchdog". The principle is that (on systems supporting it),
each thread will have its own CPU timer which progresses as the thread
consumes CPU cycles, and when a deadline is met, a signal is delivered
(SIGALRM here since it doesn't interrupt gdb by default).

The thread handling this signal (which is not necessarily the one which
triggered the timer) figures the thread ID from the signal arguments and
checks if it's really stuck by looking at the time spent since last exit
from poll() and by checking that the thread's scheduler is still alive
(so that even when dealing with configuration issues resulting in insane
amount of tasks being called in turn, it is not possible to accidently
trigger it). Checking the scheduler's activity will usually result in a
second chance, thus doubling the detecting time.

In order not to incorrectly flag a thread as being the cause of the
lockup, the thread_harmless_mask is checked : a thread could very well
be spinning on itself waiting for all other threads to join (typically
what happens when issuing "show sess"). In this case, once all threads
but one (or two) have joined, all the innocent ones are marked harmless
and will not trigger the timer. Only the ones not reacting will.

The deadline is set to one second, which already appears impossible to
reach, especially since it's 1 second of CPU usage, not elapsed time
with the CPU being preempted by other threads/processes/hypervisor. In
practice due to the scheduler's health verification it takes up to two
seconds to decide to panic.

Once all conditions are met, the goal is to crash from the offending
thread. So if it's the current one, we call ha_panic() otherwise the
signal is bounced to the offending thread which deals with it. This
will result in all threads being woken up in turn to dump their context,
the whole state is emitted on stderr in hope that it can be logged, and
the process aborts, leaving a chance for a core to be dumped and for a
service manager to restart it.

An alternative mechanism could be implemented for systems unable to
wake up a thread once its CPU clock reaches a deadline (e.g. FreeBSD).
Instead of waking the timer each and every deadline, it is possible to
use a standard timer which is reset each time we leave poll(). Since
the signal handler rechecks the CPU consumption this will also work.
However a totally idle process may trigger it from time to time which
may or may not confuse some debugging sessions. The same is true for
alarm() which could be another option for systems not having such a
broad choice of timers (but it seems that in this case they will not
have per-thread CPU measurements available either).

The feature is currently implemented only when threads are enabled in
order to keep the code clean, since the main purpose is to detect and
address inter-thread deadlocks. But if it proves useful for other
situations this condition might be relaxed.

6 years agoMINOR: threads: add a timer_t per thread in thread_info
Willy Tarreau [Tue, 21 May 2019 18:01:26 +0000 (20:01 +0200)] 
MINOR: threads: add a timer_t per thread in thread_info

This will be used by the watchdog to detect that a thread locked up.
It's only defined on platforms supporting it. This patch only reserves
the room for the timer in the struct. A special value was reserved for
the uninitialized timer. The problem is that the POSIX API was horribly
designed, defining no invalid value, thus for each timer it is required
to keep a second variable to indicate whether it's valid. A quick check
shows that defining a 32-bit invalid value is not something uncommon
across other implementations, with ~0 being common. Let's try with this
and if it causes issues we can revisit this decision.

6 years agoMINOR: threads: add a "stuck" flag to the thread_info struct
Willy Tarreau [Wed, 22 May 2019 05:06:44 +0000 (07:06 +0200)] 
MINOR: threads: add a "stuck" flag to the thread_info struct

This flag is constantly cleared by the scheduler and will be set by the
watchdog timer to detect stuck threads. It is also set by the "show
threads" command so that it is easy to spot if the situation has evolved
between two subsequent calls : if the first "show threads" shows no stuck
thread and the second one shows such a stuck thread, it indicates that
this thread didn't manage to make any forward progress since the previous
call, which is extremely suspicious.

6 years agoMINOR: debug: dump streams when an applet, iocb or stream is known
Willy Tarreau [Wed, 22 May 2019 07:43:09 +0000 (09:43 +0200)] 
MINOR: debug: dump streams when an applet, iocb or stream is known

Whenever we can retrieve a valid stream pointer, we now call stream_dump()
to get a detailed dump of the stream currently running on the processor.
This is used by "show threads" and by ha_panic().

6 years agoMINOR: stream: introduce a stream_dump() function and use it in stream_dump_and_crash()
Willy Tarreau [Wed, 22 May 2019 07:33:03 +0000 (09:33 +0200)] 
MINOR: stream: introduce a stream_dump() function and use it in stream_dump_and_crash()

This function dumps a lot of information about a stream into the provided
buffer. It is now used by stream_dump_and_crash() and will be used by the
debugger as well.

6 years agoCLEANUP: debug: make use of ha_tkill() and remove ifdefs
Willy Tarreau [Wed, 22 May 2019 06:46:59 +0000 (08:46 +0200)] 
CLEANUP: debug: make use of ha_tkill() and remove ifdefs

This way we always signal the threads the same way.

6 years agoMINOR: threads: implement ha_tkill() and ha_tkillall()
Willy Tarreau [Wed, 22 May 2019 06:43:34 +0000 (08:43 +0200)] 
MINOR: threads: implement ha_tkill() and ha_tkillall()

These functions are used respectively to signal one thread or all threads.
When multithreading is disabled, it's always the current thread which is
signaled.

6 years agoCLEANUP: debug: always report harmless/want_rdv even without threads
Willy Tarreau [Wed, 22 May 2019 06:52:58 +0000 (08:52 +0200)] 
CLEANUP: debug: always report harmless/want_rdv even without threads

This way we have a more consistent output and we can remove annoying
ifdefs.

6 years agoMINOR: threads: make threads_{harmless|want_rdv}_mask constant 0 without threads
Willy Tarreau [Wed, 22 May 2019 05:48:18 +0000 (07:48 +0200)] 
MINOR: threads: make threads_{harmless|want_rdv}_mask constant 0 without threads

Some code starts to add ifdefs everywhere to work around the lack of
threads_harmless_mask when threads are not compiled in. This one is
often used to indicate a thread having joined the rendez-vous point or
a thread sleeping in the poller. By setting it to zero we translate
what usually is required in debugging code (i.e. the only thread is
currently working) and for signal handlers we can use a combination of
threads_harmless_mask and sleeping_threads_mask to detect the polling
cases as well. Similarly do the same with threads_want_rdv_mask which
is less often used though.

6 years agoCLEANUP: threads: really move thread_info to hathreads.c
Willy Tarreau [Wed, 22 May 2019 04:42:27 +0000 (06:42 +0200)] 
CLEANUP: threads: really move thread_info to hathreads.c

Commit 5a6e2245f ("REORG: threads: move the struct thread_info from
global.h to hathreads.h") didn't hold its promise well, as the thread_info
struct was still declared and initialized in haproxy.c in addition to being
in hathreads.c. Let's move it for real now.

6 years agoMINOR: debug: switch to SIGURG for thread dumps
Willy Tarreau [Wed, 22 May 2019 04:28:54 +0000 (06:28 +0200)] 
MINOR: debug: switch to SIGURG for thread dumps

The current choice of SIGPWR has the adverse effect of stopping gdb each
time it is triggered using "show threads" or example, which is not really
convenient. Let's switch to SIGURG instead, which we don't use either.

6 years agoCLEANUP: objtype: make obj_type() and obj_type_name() take consts
Willy Tarreau [Wed, 22 May 2019 07:30:09 +0000 (09:30 +0200)] 
CLEANUP: objtype: make obj_type() and obj_type_name() take consts

There is no reason for them to require a writable area.

6 years agoBUG/MINOR: mworker: Fix memory leak of mworker_proc members
Tim Duesterhus [Thu, 16 May 2019 18:23:22 +0000 (20:23 +0200)] 
BUG/MINOR: mworker: Fix memory leak of mworker_proc members

The struct mworker_proc is not uniformly freed everywhere, sometimes leading
to leaks of the `id` string (and possibly the other strings).

Introduce a mworker_free_child function instead of duplicating the freeing
logic everywhere to prevent this kind of issues.

This leak was reported in issue #96.

It looks like the leaks have been introduced in commit 9a1ee7ac31c56fd7d881adf2ef4659f336e50c9f,
which is specific to 2.0-dev. Backporting `mworker_free_child` might be
helpful to ease backporting other fixes, though.

6 years agoCLEANUP: time: switch clockid_t to empty_t when not available
Willy Tarreau [Tue, 21 May 2019 17:58:16 +0000 (19:58 +0200)] 
CLEANUP: time: switch clockid_t to empty_t when not available

This is cleaner than using an int. We also get rid of the constants
that we don't need nor use.

6 years agoMINOR: compat: define a new empty type empty_t for non-implemented fields
Willy Tarreau [Tue, 21 May 2019 17:48:44 +0000 (19:48 +0200)] 
MINOR: compat: define a new empty type empty_t for non-implemented fields

Some structures have optional fields which depend on availability of
certain features on certain platforms, and having to stuff lots of
ifdefs in these structs makes them unreadable. Using real values like
ints requires some initialization and adds even more confusion.

Here we take a different approach : we create an empty type called
empty_t to use as a substitute for the real type that is not implemented
and which doesn't contain any value (it's an empty struct). Thus it has
a size of zero but an address, thus a pointer may point to it. It will
not have to be initialized though. Some initialization code might even
continue to work and do nothing like initializing it using memset with
its sizeof which is zero.

6 years agoCLEANUP: time: refine the test on _POSIX_TIMERS
Willy Tarreau [Tue, 21 May 2019 17:46:58 +0000 (19:46 +0200)] 
CLEANUP: time: refine the test on _POSIX_TIMERS

The clock_gettime() man page says we must check that _POSIX_TIMERS is
defined to a value greater than zero, not just that it's simply defined
so let's fix this right now.

6 years agoBUG/MEDIUM: streams: Don't switch from SI_ST_CON to SI_ST_DIS on read0.
Olivier Houchard [Tue, 21 May 2019 15:43:50 +0000 (17:43 +0200)] 
BUG/MEDIUM: streams: Don't switch from SI_ST_CON to SI_ST_DIS on read0.

When we receive a read0, and we're still in SI_ST_CON state (so on an
outgoing conneciton), don't immediately switch to SI_ST_DIS, or, we would
never call sess_establish(), and so the analysers will never run.
Instead, let sess_establish() handle that case, and switch to SI_ST_DIS if
we already have CF_SHUTR on the channel.

This should be backported to 1.9.

6 years agoMAJOR: polling: add event ports support (Solaris)
Emmanuel Hocdet [Mon, 8 Apr 2019 16:53:32 +0000 (16:53 +0000)] 
MAJOR: polling: add event ports support (Solaris)

Event ports are kqueue/epoll polling class for Solaris. Code is based
on https://github.com/joyent/haproxy-1.8/tree/joyent/dev-v1.8.8.
Event ports are available only on SunOS systems derived from
Solaris 10 and later (including illumos systems).

6 years agoBUILD: makefile: remove -fomit-frame-pointer optimisation (solaris)
Emmanuel Hocdet [Fri, 17 May 2019 15:32:21 +0000 (15:32 +0000)] 
BUILD: makefile: remove -fomit-frame-pointer optimisation (solaris)

-fomit-frame-pointer is commonly avoided because tools like dtrace
needs frame-pointer. Remove it from Makefile and let builder's env
do the job.

This patch could be backported to 1.9.

6 years agoBUILD: makefile: use USE_OBSOLETE_LINKER for solaris
Emmanuel Hocdet [Tue, 21 May 2019 09:12:03 +0000 (09:12 +0000)] 
BUILD: makefile: use USE_OBSOLETE_LINKER for solaris

USE_OBSOLETE_LINKER is needed to build on SunOS systems.

This patch must be backported to 1.9.

6 years agoBUILD: threads: only assign the clock_id when supported
Willy Tarreau [Tue, 21 May 2019 13:14:08 +0000 (15:14 +0200)] 
BUILD: threads: only assign the clock_id when supported

I took extreme care to always check for _POSIX_THREAD_CPUTIME before
manipulating clock_id, except at one place (run_thread_poll_loop) as
found by Manu, breaking Solaris. Now fixed, no backport needed.

6 years agoMINOR: debug: report each thread's cpu usage in "show thread"
Willy Tarreau [Mon, 20 May 2019 18:52:20 +0000 (20:52 +0200)] 
MINOR: debug: report each thread's cpu usage in "show thread"

Now we can report each thread's CPU time, both at wake up (poll) and
retrieved while dumping (now), then the difference, which directly
indicates how long the thread has been running uninterrupted. A very
high value for the diff could indicate a deadlock, especially if it
happens between two threads. Note that it may occasionally happen
that a wrong value is displayed since nothing guarantees that the
date is read atomically.

6 years agoMINOR: time: add a function to retrieve another thread's cputime
Willy Tarreau [Mon, 20 May 2019 18:28:34 +0000 (20:28 +0200)] 
MINOR: time: add a function to retrieve another thread's cputime

now_cpu_time_thread() does the same as now_cpu_time() but for another
thread based on its clockid.

6 years agoMINOR: time: move the cpu, mono, and idle time to thread_info
Willy Tarreau [Mon, 20 May 2019 17:24:50 +0000 (19:24 +0200)] 
MINOR: time: move the cpu, mono, and idle time to thread_info

These ones are useful across all threads and would be better placed
in struct thread_info than thread-local. There are very few users.

6 years agoMINOR: threads: add a thread-local thread_info pointer "ti"
Willy Tarreau [Mon, 20 May 2019 16:57:53 +0000 (18:57 +0200)] 
MINOR: threads: add a thread-local thread_info pointer "ti"

Since we're likely to access this thread_info struct more frequently in
the future, let's reserve the thread-local symbol to access it directly
and avoid always having to combine thread_info and tid. This pointer is
set when tid is set.

6 years agoMINOR: threads: always place the clockid in the struct thread_info
Willy Tarreau [Mon, 20 May 2019 18:23:06 +0000 (20:23 +0200)] 
MINOR: threads: always place the clockid in the struct thread_info

It will be easier to deal with the internal API to always have it.

6 years agoMINOR: compat: make sure to always define clockid_t
Willy Tarreau [Mon, 20 May 2019 18:18:26 +0000 (20:18 +0200)] 
MINOR: compat: make sure to always define clockid_t

In order to ease the internal time API, we'll have the threads time always
present even when threads are disabled. Let's make sure clockid_t, and the
minimum clock times are defined even on older or non-compatible systems.

6 years agoREORG: threads: move the struct thread_info from global.h to hathreads.h
Willy Tarreau [Mon, 20 May 2019 16:56:48 +0000 (18:56 +0200)] 
REORG: threads: move the struct thread_info from global.h to hathreads.h

It doesn't make sense to keep this struct thread_info in global.h, it
causes difficulties to access its contents from hathreads.h, let's move
it to the threads where it ought to have been created.

6 years agoREORG: compat: move some integer limit definitions from standard.h to compat.h
Willy Tarreau [Mon, 20 May 2019 17:10:52 +0000 (19:10 +0200)] 
REORG: compat: move some integer limit definitions from standard.h to compat.h

Historically standard.h was the location where we used to (re-)define the
standard set of macros and functions, and to complement the ones missing
on the target OS. Over time it has become a toolbox in itself relying on
many other things, and its definition of LONGBITS is used everywhere else
(e.g. for MAX_THREADS), resulting in painful circular dependencies.

Let's move these few defines (integer sizes) to compat.h where other
similar definitions normally are.

6 years agoMINOR: debug: make ha_panic() report threads starting at 1
Willy Tarreau [Mon, 20 May 2019 15:45:35 +0000 (17:45 +0200)] 
MINOR: debug: make ha_panic() report threads starting at 1

Internally they start at zero but everywhere (config, dumps) we show
them starting at 1, so let's fix the confusion.

6 years agoMINOR: tools: provide a may_access() function and make dump_hex() use it
Willy Tarreau [Mon, 20 May 2019 14:48:20 +0000 (16:48 +0200)] 
MINOR: tools: provide a may_access() function and make dump_hex() use it

It's a bit too easy to crash by accident when using dump_hex() on any
area. Let's have a function to check if the memory may safely be read
first. This one abuses the stat() syscall checking if it returns EFAULT
or not, in which case it means we're not allowed to read from there. In
other situations it may return other codes or even a success if the
area pointed to by the file exists. It's important not to abuse it
though and as such it's tested only once per output line.

6 years agoMINOR: debug/cli: add some debugging commands for developers
Willy Tarreau [Mon, 20 May 2019 12:25:05 +0000 (14:25 +0200)] 
MINOR: debug/cli: add some debugging commands for developers

When haproxy is built with DEBUG_DEV, the following commands are added
to the CLI :

  debug dev close <fd>        : close this file descriptor
  debug dev delay [ms]        : sleep this long
  debug dev exec  [cmd] ...   : show this command's output
  debug dev exit  [code]      : immediately exit the process
  debug dev hex   <addr> [len]: dump a memory area
  debug dev log   [msg] ...   : send this msg to global logs
  debug dev loop  [ms]        : loop this long
  debug dev panic             : immediately trigger a panic
  debug dev tkill [thr] [sig] : send signal to thread

These are essentially aimed at helping developers trigger certain
conditions and are expected to be complemented over time.

6 years agoMINOR: debug: implement ha_panic()
Willy Tarreau [Mon, 20 May 2019 11:48:29 +0000 (13:48 +0200)] 
MINOR: debug: implement ha_panic()

This function dumps all existing threads using the thread dump mechanism
then aborts. This will be used by the lockup detection and by debugging
tools.

6 years agoMINOR: tools: add dump_hex()
Willy Tarreau [Mon, 20 May 2019 14:13:40 +0000 (16:13 +0200)] 
MINOR: tools: add dump_hex()

This is used to dump a memory area into a buffer for debugging purposes.

6 years agoCLEANUP: stream: remove an obsolete debugging test
Willy Tarreau [Mon, 20 May 2019 14:18:13 +0000 (16:18 +0200)] 
CLEANUP: stream: remove an obsolete debugging test

The test consisted in checking that there was always a timeout on a
stream's task and was only enabled when built in development mode,
but 1) it is never tested and 2) if it had been tested it would have
been noticed that it triggers a bit too easily on the CLI. Let's get
rid of this old one.

6 years agoMINOR: threads: add each thread's clockid into the global thread_info
Willy Tarreau [Fri, 3 May 2019 15:21:18 +0000 (17:21 +0200)] 
MINOR: threads: add each thread's clockid into the global thread_info

This is the per-thread CPU runtime clock, it will be used to measure
the CPU usage of each thread and by the lockup detection mechanism. It
must only be retrieved at the beginning of run_thread_poll_loop() since
the thread must already have been started for this. But it must be done
before performing any per-thread initcall so that all thread init
functions have access to the clock ID.

Note that it could make sense to always have this clockid available even
in non-threaded situations and place the process' clock there instead.
But it would add portability issues which are currently easy to deal
with by disabling threads so it may not be worth it for now.

6 years agoMINOR: init/threads: make the global threads an array of structs
Willy Tarreau [Fri, 3 May 2019 08:16:39 +0000 (10:16 +0200)] 
MINOR: init/threads: make the global threads an array of structs

This way we'll be able to store more per-thread information than just
the pthread pointer. The storage became an array of struct instead of
an allocated array since it's very small (typically 512 bytes) and not
worth the hassle of dealing with memory allocation on this. The array
was also renamed thread_info to make its intended usage more explicit.

6 years agoCLEANUP: threads: remove the now unused START_LOCK label
Willy Tarreau [Mon, 20 May 2019 09:14:51 +0000 (11:14 +0200)] 
CLEANUP: threads: remove the now unused START_LOCK label

The last two users are now gone.

6 years agoCLEANUP: memory: make the fault injection code use the OTHER_LOCK label
Willy Tarreau [Mon, 20 May 2019 09:09:00 +0000 (11:09 +0200)] 
CLEANUP: memory: make the fault injection code use the OTHER_LOCK label

The mem_should_fail() function sets a lock while it's building its
messages, and when this was done there was no relevant label available
hence the confusing use of START_LOCK. Now OTHER_LOCK is available for
such use cases, so let's switch to this one instead as START_LOCK is
going to disappear.

6 years agoMEDIUM: init/mworker: make the pipe register function a regular initcall
Willy Tarreau [Mon, 20 May 2019 09:12:15 +0000 (11:12 +0200)] 
MEDIUM: init/mworker: make the pipe register function a regular initcall

Now that we have the guarantee that init calls happen before any other
thread starts, we don't need anymore the workaround installed by commit
1605c7ae6 ("BUG/MEDIUM: threads/mworker: fix a race on startup") and we
can instead rely on a regular per-thread initcall for this function. It
will only be performed on worker thread #0, the other ones and the master
have nothing to do, just like in the original code that was only moved
to the function.

6 years agoMINOR: threads/init: synchronize the threads startup
Willy Tarreau [Mon, 20 May 2019 08:50:43 +0000 (10:50 +0200)] 
MINOR: threads/init: synchronize the threads startup

It's a bit dangerous to let threads initialize at different speeds on
startup. Some are still in their init functions while others area already
running. It was even subject to some race condition bugs like the one
fixed by commit 1605c7ae6 ("BUG/MEDIUM: threads/mworker: fix a race on
startup").

Here in order to secure all this, we take a very simplistic approach
consisting in using half of the rendez-vous point, which is made
exactly for this purpose : we first initialize the mask of the threads
requesting a rendez-vous to the mask of all threads, and we simply call
thread_release() once the init is complete. This guarantees that no
thread will go further than the initialization code during this time.

This could even safely be backported if any other issue related to an
init race was discovered in a stable release.

6 years agoMINOR: init: setenv HAPROXY_CFGFILES
William Lallemand [Mon, 20 May 2019 09:15:37 +0000 (11:15 +0200)] 
MINOR: init: setenv HAPROXY_CFGFILES

Set the HAPROXY_CFGFILES environment variable which contains the list of
configuration files used to start haproxy, separated by semicolon.

6 years agoDOC: fix "successful" typo
Bertrand Jacquin [Thu, 16 May 2019 21:15:31 +0000 (22:15 +0100)] 
DOC: fix "successful" typo

s/succesfull/successful at a few places

6 years agoREGTEST: extend the check duration on tls_health_checks and mark it slow
Willy Tarreau [Fri, 17 May 2019 15:15:20 +0000 (17:15 +0200)] 
REGTEST: extend the check duration on tls_health_checks and mark it slow

Even after commit 1bbc74b55 ("REGTEST: fix tls_health_checks random
failures on MacOS in Travis-CI") which extended it to 100ms, it still
randomly fails on Travis, so let's push it to 500ms and mark it slow.

6 years agoMEDIUM: debug/threads: implement an advanced thread dump system
Willy Tarreau [Fri, 17 May 2019 08:08:49 +0000 (10:08 +0200)] 
MEDIUM: debug/threads: implement an advanced thread dump system

The current "show threads" command was too limited as it was not possible
to dump other threads' detailed states (e.g. their tasks). This patch
goes further by using thread signals so that each thread can dump its
own state in turn into a shared buffer provided by the caller. Threads
are synchronized using a mechanism very similar to the rendez-vous point
and using this method, each thread can safely dump any of its contents
and the caller can finally report the aggregated ones from the buffer.

It is important to keep in mind that the list of signal-safe functions
is limited, so we take care of only using chunk_printf() to write to a
pre-allocated buffer.

This mechanism is enabled by USE_THREAD_DUMP and is enabled by default
on Linux 2.6.28+. On other platforms it falls back to the previous
solution using the loop and the less precise dump.

6 years agoMINOR: stream: detach the stream from its own task on stream_free()
Willy Tarreau [Fri, 17 May 2019 12:20:05 +0000 (14:20 +0200)] 
MINOR: stream: detach the stream from its own task on stream_free()

This makes sure that the stream is not visible from its own task just
before starting to free some of its components. This way we have the
guarantee that a stream found in a task list is totally valid and can
safely be dereferenced.

6 years agoMINOR: task: always reset curr_task when freeing a task or tasklet
Willy Tarreau [Fri, 17 May 2019 12:16:51 +0000 (14:16 +0200)] 
MINOR: task: always reset curr_task when freeing a task or tasklet

With the thread debugger it becomes visible that we can leave some
wandering pointers for a while in curr_task, which is inappropriate.
This patch addresses this by resetting curr_task to NULL before really
freeing the area. This way it becomes safe even regarding signals.

6 years agoMINOR: task: put barriers after each write to curr_task
Willy Tarreau [Fri, 17 May 2019 09:46:04 +0000 (11:46 +0200)] 
MINOR: task: put barriers after each write to curr_task

This one may be watched by signal handlers, we don't want the compiler
to optimize its assignment away at the end of the loop and leave some
wandering pointers there.

6 years agoMINOR: thread: implement ha_thread_relax()
Willy Tarreau [Fri, 17 May 2019 14:33:13 +0000 (16:33 +0200)] 
MINOR: thread: implement ha_thread_relax()

At some places we're using a painful ifdef to decide whether to use
sched_yield() or pl_cpu_relax() to relax in loops, this is hardly
exportable. Let's move this to ha_thread_relax() instead and une
this one only.

6 years agoBUG/MINOR: debug: don't check the call date on tasklets
Willy Tarreau [Fri, 17 May 2019 12:14:35 +0000 (14:14 +0200)] 
BUG/MINOR: debug: don't check the call date on tasklets

tasklets don't have a call date, so when a tasklet is cast into a task
and is present at the end of a page we run a risk of dereferencing
unmapped memory when dumping them in ha_task_dump(). This commit
simplifies the test and uses to distinct calls for tasklets and tasks.
No backport is needed.

6 years agoMINOR: debug: make ha_thread_dump() and ha_task_dump() take a buffer
Willy Tarreau [Fri, 17 May 2019 08:36:08 +0000 (10:36 +0200)] 
MINOR: debug: make ha_thread_dump() and ha_task_dump() take a buffer

Instead of having them dump into the trash and initialize it, let's have
the caller initialize a buffer and pass it. This will be convenient to
dump multiple threads at once into a single buffer.

6 years agoBUG/MINOR: debug: make ha_task_dump() actually dump the requested task
Willy Tarreau [Fri, 17 May 2019 08:34:25 +0000 (10:34 +0200)] 
BUG/MINOR: debug: make ha_task_dump() actually dump the requested task

It used to only dump the current task, which isn't different for now
but the purpose clearly is to dump the requested task. No backport is
needed.

6 years agoBUG/MINOR: debug: make ha_task_dump() always check the task before dumping it
Willy Tarreau [Fri, 17 May 2019 08:39:47 +0000 (10:39 +0200)] 
BUG/MINOR: debug: make ha_task_dump() always check the task before dumping it

For now it cannot happen since we're calling it from a task but it will
break with signals. No backport is needed.

6 years agoBUG/MEDIUM: streams: Try to L7 retry before aborting the connection.
Olivier Houchard [Fri, 17 May 2019 13:40:49 +0000 (15:40 +0200)] 
BUG/MEDIUM: streams: Try to L7 retry before aborting the connection.

In htx_wait_for_response, in case of error, attempt a L7 retry before
aborting the connection if the TX_NOT_FIRST flag is set.
If we don't do that, then we wouldn't attempt L7 retries after the first
request, or if we use HTTP/2, as with HTTP/2 that flag is always set.

6 years agoBUG/MEDIUM: streams: Don't use CF_EOI to decide if the request is complete.
Olivier Houchard [Fri, 17 May 2019 13:38:29 +0000 (15:38 +0200)] 
BUG/MEDIUM: streams: Don't use CF_EOI to decide if the request is complete.

In si_cs_send(), don't check CF_EOI on the request channel to decide if the
request is complete and if we should save the buffer to eventually attempt
L7 retries. The flag may not be set yet, and it may too be set to early,
before we're done modifying the buffer. Instead, get the msg, and make sure
its state is HTTP_MSG_DONE.
That way we will store the request buffer when sending it even in H2.

6 years agoMINOR: cli/debug: add a thread dump function
Willy Tarreau [Thu, 16 May 2019 15:44:30 +0000 (17:44 +0200)] 
MINOR: cli/debug: add a thread dump function

The new function ha_thread_dump() will dump debugging info about all known
threads. The current thread will contain a bit more info. The long-term goal
is to make it possible to use it in signal handlers to improve the accuracy
of some dumps.

The function dumps its output into the trash so as it was trivial to add,
a new "show threads" command appeared on the CLI.

6 years agoMINOR: task: export global_task_mask
Willy Tarreau [Thu, 16 May 2019 15:37:27 +0000 (17:37 +0200)] 
MINOR: task: export global_task_mask

It will be used in debugging functions and must be exported.

6 years agoMINOR: cli/activity: show the dumping thread ID starting at 1
Willy Tarreau [Thu, 16 May 2019 14:19:47 +0000 (16:19 +0200)] 
MINOR: cli/activity: show the dumping thread ID starting at 1

Both the config and gdb report thread IDs starting at 1, so better do the
same in "show activity" to limit confusion. We also display the full
permitted range.

This could be backported to 1.9 since it was present there.

6 years agoDOC: management: place "show activity" at the right place
Willy Tarreau [Thu, 16 May 2019 15:39:32 +0000 (17:39 +0200)] 
DOC: management: place "show activity" at the right place

This time it seems to be me who had trouble with alphabetical ordering.
This should be backported to 1.9.

6 years agoMEDIUM: Make 'resolution_pool_size' directive fatal
Tim Duesterhus [Tue, 14 May 2019 18:57:56 +0000 (20:57 +0200)] 
MEDIUM: Make 'resolution_pool_size' directive fatal

This directive never appeared in a stable release and instead was
introduced and deprecated within 1.8-dev. While it technically could
be outright removed we detect it and error out for good measure.