]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
4 years agoMINOR: tcp_samples: Add samples to get src/dst info of the backend connection
Christopher Faulet [Thu, 15 Apr 2021 07:38:37 +0000 (09:38 +0200)] 
MINOR: tcp_samples: Add samples to get src/dst info of the backend connection

This patch adds 4 new sample fetches to get the source and the destination
info (ip address and port) of the backend connection :

 * bc_dst      : Returns the destination address of the backend connection
 * bc_dst_port : Returns the destination port of the backend connection
 * bc_src      : Returns the source address of the backend connection
 * bc_src_port : Returns the source port of the backend connection

The configuration manual was updated accordingly.

4 years agoBUG/MINOR: http-fetch: Make method smp safe if headers were already forwarded
Christopher Faulet [Thu, 15 Apr 2021 07:28:02 +0000 (09:28 +0200)] 
BUG/MINOR: http-fetch: Make method smp safe if headers were already forwarded

When method sample fetch is called, if an exotic method is found
(HTTP_METH_OTHER), when smp_prefetch_htx() is called, we must be sure the
start-line is still there. Otherwise, HAproxy may crash because of a NULL
pointer dereference, for instance if the method sample fetch is used inside
a unique-id format string. Indeed, the unique id may be generated when the
log message is emitted. At this stage, the request channel is empty.

This patch must be backported as far as 2.0. But the bug exists in all
stable versions for the legacy HTTP mode too. Thus it must be adapted to the
legacy HTTP mode and backported to all other stable versions.

4 years agoBUG/MINOR: ssl-samples: Fix ssl_bc_* samples when called from a health-check
Christopher Faulet [Wed, 14 Apr 2021 13:49:41 +0000 (15:49 +0200)] 
BUG/MINOR: ssl-samples: Fix ssl_bc_* samples when called from a health-check

For all ssl_bc_* sample fetches, the test on the keyword when called from a
health-check is inverted. We must be sure the 5th charater is a 'b' to
retrieve a connection.

This patch must be backported as far as 2.2.

4 years agoMINOR: connection: Make bc_http_major compatible with tcp-checks
Christopher Faulet [Wed, 14 Apr 2021 13:46:49 +0000 (15:46 +0200)] 
MINOR: connection: Make bc_http_major compatible with tcp-checks

bc_http_major sample fetch now works when it is called from a
tcp-check. When it happens, the session origin is a check. The backend
connection is retrieved from the conn-stream attached to the check.

If required, this path may easily be backported as far as 2.2.

4 years agoBUG/MINOR: connection: Fix fc_http_major and bc_http_major for TCP connections
Christopher Faulet [Wed, 14 Apr 2021 13:40:30 +0000 (15:40 +0200)] 
BUG/MINOR: connection: Fix fc_http_major and bc_http_major for TCP connections

fc_http_major and bc_http_major sample fetches return the major digit of the
HTTP version used, respectively, by the frontend and the backend
connections, based on the mux. However, in reality, "2" is returned if the
H2 mux is detected, otherwise "1" is inconditionally returned, regardless
the mux used. Thus, if called for a raw TCP connection, "1" is returned.

To fix this bug, we now get the multiplexer flags, if there is one, to be
sure MX_FL_HTX is set.

I guess it was made this way on purpose when the H2 multiplexer was
introduced in the 1.8 and with the legacy HTTP mode there is no other
solution at the connection level. Thus this patch should be backported as
far as 2.2. For the 2.0, it must be evaluated first because of the legacy
HTTP mode.

4 years agoMINOR: logs: Add support of checks as session origin to format lf strings
Christopher Faulet [Wed, 14 Apr 2021 12:01:41 +0000 (14:01 +0200)] 
MINOR: logs: Add support of checks as session origin to format lf strings

When a log-format string is built from an health-check, the session origin
is the health-check itself and not a connection. In addition, there is no
stream. It means for now some formats are not supported: %s, %sc, %b, %bi,
%bp, %si and %sp.

Thanks to this patch, the session origin is converted to a check. So it is
possible to retrieve the backend and the backend connection. Note this
session have no listener, thus %ft format must be guarded.

This patch is light and standalone, thus it may be backported as far as 2.2
if required. However, because the error is human, it is probably better to
wait a bit to be sure everything is properly protected.

4 years agoBUG/MINOR: checks: Set missing id to the dummy checks frontend
Christopher Faulet [Fri, 16 Apr 2021 08:49:07 +0000 (10:49 +0200)] 
BUG/MINOR: checks: Set missing id to the dummy checks frontend

The dummy frontend used to create the session of the tcp-checks is
initialized without identifier. However, it is required because this id may
be used without any guard, for instance in log-format string via "%f" or
when fe_name sample fetch is called. Thus, an unset id may lead to crashes.

This patch must be backported as far as 2.2.

4 years agoMINOR: threads: Only consider running threads to end a thread harmeless period
Christopher Faulet [Fri, 16 Apr 2021 09:33:39 +0000 (11:33 +0200)] 
MINOR: threads: Only consider running threads to end a thread harmeless period

When a thread ends its harmeless period, we must only consider running
threads when testing threads_want_rdv_mask mask. To do so, we reintroduce
all_threads_mask mask in the bitwise operation (It was removed to fix a
deadlock).

Note that for now it is useless because there is no way to stop threads or
to have threads reserved for another task. But it is safer this way to avoid
bugs in the future.

4 years agoBUG/MEDIUM: threads: Ignore current thread to end its harmless period
Christopher Faulet [Wed, 14 Apr 2021 12:02:25 +0000 (14:02 +0200)] 
BUG/MEDIUM: threads: Ignore current thread to end its harmless period

A previous patch was pushed to fix a deadlock when an isolated thread ends
its harmless period (a9a9e9aac ["BUG/MEDIUM: thread: Fix a deadlock if an
isolated thread is marked as harmless"]). But, unfortunately, the fix is
incomplete. The same must be done in the outer loop, in
thread_harmless_end() function. The current thread must be ignored when
threads_want_rdv_mask mask is tested.

This patch must also be backported as far as 2.0.

4 years agoDOC: ssl: Certificate hot update works on server certificates
Remi Tricot-Le Breton [Wed, 14 Apr 2021 14:19:29 +0000 (16:19 +0200)] 
DOC: ssl: Certificate hot update works on server certificates

The CLI's "set ssl cert" command also works on backend certificates
(see GitHub issue #427).

It does not need to be backported.

4 years agoDOC: ssl: Certificate hot update only works on fronted certificates
Remi Tricot-Le Breton [Wed, 14 Apr 2021 14:19:28 +0000 (16:19 +0200)] 
DOC: ssl: Certificate hot update only works on fronted certificates

The CLI's "set ssl cert" command only works on frontend certificates but
the documentation did not specify this limitations yet.

This patch can be backported to all stable branches.

4 years agoCI: travis-ci: enable weekly graviton2 builds
Ilya Shipitsin [Thu, 15 Apr 2021 14:16:09 +0000 (19:16 +0500)] 
CI: travis-ci: enable weekly graviton2 builds

as documented in https://blog.travis-ci.com/2020-09-11-arm-on-aws
we can build on graviton2, let us expand travis-ci matrix to that
machine type as well

4 years agoMINOR: sample: converter: Add json_query converter
Alex [Thu, 15 Apr 2021 14:45:15 +0000 (16:45 +0200)] 
MINOR: sample: converter: Add json_query converter

With the json_query can a JSON value be extacted from a header
or body of the request and saved to a variable.

This converter makes it possible to handle some JSON workload
to route requests to different backends.

4 years agoMINOR: sample: converter: Add mjson library.
Alex [Thu, 15 Apr 2021 11:46:25 +0000 (13:46 +0200)] 
MINOR: sample: converter: Add mjson library.

This library is required for the subsequent patch which adds
the JSON query possibility.

It is necessary to change the include statement in "src/mjson.c"
because the imported includes in haproxy are in "include/import"

orig: #include "mjson.h"
new:  #include <import/mjson.h>

4 years agoMINOR: opentracing: transfer of context names without prefix
Miroslav Zagorac [Wed, 14 Apr 2021 09:47:28 +0000 (11:47 +0200)] 
MINOR: opentracing: transfer of context names without prefix

In order to enable the assignment of a context name, and yet exclude the
use of that name (prefix in this case) when extracting the context from
the HTTP header, a special character '-' has been added, which can be
specified at the beginning of the prefix.

So let's say if we look at examples of the fe-be configuration, we can
transfer the context via an HTTP header without a prefix like this:

  fe/ot.cfg:
        ..
        span "HAProxy session"
            inject "" use-headers
        event on-backend-http-request

Such a context can be read in another process using a name that has a
special '-' sign at the beginning:

  be/ot.cfg:
    ot-scope frontend_http_request
        extract "-ot-ctx" use-headers
        span "HAProxy session" child-of "-ot-ctx" root
        ..

This means that the context name will be '-ot-ctx' but it will not be
used when extracting data from HTTP headers.

Of course, if the context does not have a prefix set, all HTTP headers
will be inserted into the OpenTracing library as context.  All of the
above will only work correctly if that library can figure out what is
relevant to the context and what is not.

4 years agoMINOR: opentracing: correct calculation of the number of arguments in the args[]
Miroslav Zagorac [Wed, 14 Apr 2021 09:44:58 +0000 (11:44 +0200)] 
MINOR: opentracing: correct calculation of the number of arguments in the args[]

It is possible that some arguments within the configuration line are not
specified; that is, they are set to a blank string.

For example:
  keyword '' arg_2

In that case the content of the args field will be like this:
  args[0]:                  'keyword'
  args[1]:                  NULL pointer
  args[2]:                  'arg_2'
  args[3 .. MAX_LINE_ARGS): NULL pointers

The previous way of calculating the number of arguments (as soon as a
null pointer is encountered) could not place an argument on an empty
string.

All of the above is essential for passing the OpenTracing context via
the HTTP headers (keyword 'inject'), where one of the arguments is the
context name prefix.  This way we can set an empty prefix, which is very
useful if we get context from some other process that can't add a prefix
to that data; or we want to pass the context to some process that cannot
handle the prefix of that data.

4 years agoCI: cirrus: install "pcre" package
Ilya Shipitsin [Wed, 14 Apr 2021 16:47:34 +0000 (21:47 +0500)] 
CI: cirrus: install "pcre" package

it turned out that our cirrus-ci freebsd builds got broken because
of missing "pcre". Most probably it was installed earlier as a dependency.
let us install it directly.

4 years agoMINOR: ist: Add `istclear(struct ist*)`
Tim Duesterhus [Wed, 14 Apr 2021 17:14:30 +0000 (19:14 +0200)] 
MINOR: ist: Add `istclear(struct ist*)`

istclear allows one to easily reset an ist to zero-size, while preserving the
previous size, indicating the length of the underlying buffer.

4 years agoCLEANUP: sample: align samples list in sample.c
Moemen MHEDHBI [Thu, 1 Apr 2021 23:05:07 +0000 (01:05 +0200)] 
CLEANUP: sample: align samples list in sample.c

4 years agoMINOR: sample: add ub64dec and ub64enc converters
Moemen MHEDHBI [Thu, 1 Apr 2021 18:53:59 +0000 (20:53 +0200)] 
MINOR: sample: add ub64dec and ub64enc converters

ub64dec and ub64enc are the base64url equivalent of b64dec and base64
converters. base64url encoding is the "URL and Filename Safe Alphabet"
variant of base64 encoding. It is also used in in JWT (JSON Web Token)
standard.
RFC1421 mention in base64.c file is deprecated so it was replaced with
RFC4648 to which existing converters, base64/b64dec, still apply.

Example:
  HAProxy:
    http-request return content-type text/plain lf-string %[req.hdr(Authorization),word(2,.),ub64dec]
  Client:
    Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZm9vIiwia2V5IjoiY2hhZTZBaFhhaTZlIn0.5VsVj7mdxVvo1wP5c0dVHnr-S_khnIdFkThqvwukmdg
    $ curl -H "Authorization: Bearer ${TOKEN}" http://haproxy.local
    {"user":"foo","key":"chae6AhXai6e"}

4 years agoBUG/MEDIUM: sample: Fix adjusting size in field converter
Thayne McCombs [Mon, 12 Apr 2021 05:26:59 +0000 (23:26 -0600)] 
BUG/MEDIUM: sample: Fix adjusting size in field converter

Adjust the size of the sample buffer before we change the "area"
pointer. The change in size is calculated as the difference between the
original pointer and the new start pointer. But since the
`smp->data.u.str.area` assignment results in `smp->data.u.str.area` and
`start` being the same pointer, we always ended up substracting zero.
This changes it to change the size by the actual amount it changed.

I'm not entirely sure what the impact of this is, but the previous code
seemed wrong.

[wt: from what I can see the only harmful case is when the output is
 converted to a stick-table key, it could result in zeroing past the
 end of the buffer; other cases do not touch beyond ->data]

4 years agoDOC: internals: update the SSL architecture schema
Remi Tricot-Le Breton [Mon, 12 Apr 2021 07:57:00 +0000 (09:57 +0200)] 
DOC: internals: update the SSL architecture schema

This commit adds the new fields added to the ckch_inst structure in
order to manage the backend certificate hot update (GitHub #427) and the
bug of the default certificate update (GitHub #1143).

4 years agoMINOR: cfgparse/proxy: Group alloc error handling during proxy section parsing
Christopher Faulet [Mon, 12 Apr 2021 19:31:45 +0000 (21:31 +0200)] 
MINOR: cfgparse/proxy: Group alloc error handling during proxy section parsing

All allocation errors in cfg_parse_listen() are now handled in a unique
place under the "alloc_error" label. This simplify a bit error handling in
this function.

4 years agoBUG/MINOR: cfgparse/proxy: Hande allocation errors during proxy section parsing
Christopher Faulet [Mon, 12 Apr 2021 16:46:52 +0000 (18:46 +0200)] 
BUG/MINOR: cfgparse/proxy: Hande allocation errors during proxy section parsing

At several places during the proxy section parsing, memory allocation was
performed with no check. Result is now tested and an error is returned if
the allocation fails.

This patch may be backported to all stable version but it only fixes
allocation errors during configuration parsing. Thus, it is not mandatory.

4 years agoBUG/MINOR: listener: Handle allocation error when allocating a new bind_conf
Christopher Faulet [Mon, 12 Apr 2021 14:56:37 +0000 (16:56 +0200)] 
BUG/MINOR: listener: Handle allocation error when allocating a new bind_conf

Allocation error are now handled in bind_conf_alloc() functions. Thus
callers, when not already done, are also updated to catch NULL return value.

This patch may be backported (at least partially) to all stable
versions. However, it only fix errors durung configuration parsing. Thus it
is not mandatory.

4 years agoBUG/MINOR: cfgparse/proxy: Fix some leaks during proxy section parsing
Christopher Faulet [Mon, 12 Apr 2021 14:28:30 +0000 (16:28 +0200)] 
BUG/MINOR: cfgparse/proxy: Fix some leaks during proxy section parsing

Allocated variables are now released when an error occurred during
use_backend, use-server, force/ignore-parsing, stick-table, stick and stats
directives parsing. For some of these directives, allocation errors have
been added.

This patch may be backported to all stable version but it only fixes leaks
or allocation errors during configuration parsing. Thus, it is not
mandatory. It should fix issue #1119.

4 years agoBUG/MINOR: hlua: Fix memory leaks on error path when registering a cli keyword
Christopher Faulet [Mon, 12 Apr 2021 13:31:29 +0000 (15:31 +0200)] 
BUG/MINOR: hlua: Fix memory leaks on error path when registering a cli keyword

When an error occurred in hlua_register_cli(), the allocated lua function
and keyword must be released to avoid memory leaks.

This patch depends on "MINOR: hlua: Add function to release a lua
function". It may be backported in all stable versions.

4 years agoBUG/MINOR: hlua: Fix memory leaks on error path when registering a service
Christopher Faulet [Mon, 12 Apr 2021 13:11:44 +0000 (15:11 +0200)] 
BUG/MINOR: hlua: Fix memory leaks on error path when registering a service

When an error occurred in hlua_register_service(), the allocated lua
function and keyword must be released to avoid memory leaks.

This patch depends on "MINOR: hlua: Add function to release a lua
function". It may be backported in all stable versions.

4 years agoBUG/MINOR: hlua: Fix memory leaks on error path when registering an action
Christopher Faulet [Mon, 12 Apr 2021 13:08:12 +0000 (15:08 +0200)] 
BUG/MINOR: hlua: Fix memory leaks on error path when registering an action

When an error occurred in hlua_register_action(), the allocated lua function
and keyword must be released to avoid memory leaks.

This patch depends on "MINOR: hlua: Add function to release a lua
function". It may be backported in all stable versions.

4 years agoBUG/MINOR: hlua: Fix memory leaks on error path when parsing a lua action
Christopher Faulet [Mon, 12 Apr 2021 12:37:32 +0000 (14:37 +0200)] 
BUG/MINOR: hlua: Fix memory leaks on error path when parsing a lua action

hen an error occurred in action_register_lua(), the allocated hlua rule and
arguments must be released to avoid memory leaks.

This patch may be backported in all stable versions.

4 years agoBUG/MINOR: hlua: Fix memory leaks on error path when registering a fetch
Christopher Faulet [Mon, 12 Apr 2021 12:11:50 +0000 (14:11 +0200)] 
BUG/MINOR: hlua: Fix memory leaks on error path when registering a fetch

When an error occurred in hlua_register_fetches(), the allocated lua
function and keyword must be released to avoid memory leaks.

This patch depends on "MINOR: hlua: Add function to release a lua
function". It may be backported in all stable versions. It should fix #1112.

4 years agoBUG/MINOR: hlua: Fix memory leaks on error path when registering a converter
Christopher Faulet [Mon, 12 Apr 2021 12:08:21 +0000 (14:08 +0200)] 
BUG/MINOR: hlua: Fix memory leaks on error path when registering a converter

When an error occurred in hlua_register_converters(), the allocated lua
function and keyword must be released to avoid memory leaks.

This patch depends on "MINOR: hlua: Add function to release a lua
function". It may be backported in all stable versions.

4 years agoBUG/MINOR: hlua: Fix memory leaks on error path when registering a task
Christopher Faulet [Mon, 12 Apr 2021 10:24:47 +0000 (12:24 +0200)] 
BUG/MINOR: hlua: Fix memory leaks on error path when registering a task

When an error occurred in hlua_register_task(), the allocated lua context
and task must be released to avoid memory leaks.

This patch may be backported in all stable versions.

4 years agoMINOR: hlua: Add function to release a lua function
Christopher Faulet [Mon, 12 Apr 2021 12:05:43 +0000 (14:05 +0200)] 
MINOR: hlua: Add function to release a lua function

release_hlua_function() must be used to release a lua function. Some fixes
depends on this function.

4 years agoMINOIR: checks/trace: Register a new trace source with its events
Christopher Faulet [Sat, 10 Apr 2021 07:00:38 +0000 (09:00 +0200)] 
MINOIR: checks/trace: Register a new trace source with its events

Add the trace support for the checks. Only tcp-check based health-checks are
supported, including the agent-check.

In traces, the first argument is always a check object. So it is easy to get
all info related to the check. The tcp-check ruleset, the conn-stream and
the connection, the server state...

4 years agoMINOR: trace: Add the checks as a possible trace source
Christopher Faulet [Mon, 12 Apr 2021 09:53:16 +0000 (11:53 +0200)] 
MINOR: trace: Add the checks as a possible trace source

To be able to add the trace support for the checks, a new kind of source
must be added for this purpose.

4 years agoMINOR: atomic: reimplement the relaxed version of x86 BTS/BTR
Willy Tarreau [Mon, 12 Apr 2021 07:58:31 +0000 (09:58 +0200)] 
MINOR: atomic: reimplement the relaxed version of x86 BTS/BTR

Olivier spotted that I messed up during a rebase of commit 92c059c2a
("MINOR: atomic: implement native BTS/BTR for x86"), losing the x86
version of the BTS/BTR and leaving the generic version for it instead
of having this block in the #else. Since this variant is not used for
now it was easy to overlook it. Let's re-implement it here.

4 years agoMEDIUM: time: make the clock offset global and no per-thread
Willy Tarreau [Sun, 11 Apr 2021 16:53:58 +0000 (18:53 +0200)] 
MEDIUM: time: make the clock offset global and no per-thread

Since 1.8 for simplicity the time offset used to compensate for time
drift and jumps had been stored per thread. But with a global time,
the complexit has significantly increased.

What this patch does in order to address this is to get back to the
origins of the pre-thread time drift correction, and keep a single
offset between the system's date and the current global date.

The thread first verifies from the before_poll date if the time jumped
backwards or forward, then either fixes it by computing the new most
likely date, or applies the current offset to this latest system date.
In the first case, if the date is out of range, the old one is reused
with the max_wait offset or not depending on the interrupted flag.
Then it compares its date to the global date and updates both so that
both remain monotonic and that the local date always reflects the
latest known global date.

In order to support atomic updates to the offset, it's saved as a
ullong which contains both the tv_sec and tv_usec parts in its high
and low words. Note that a part of the patch comes from the inlining
of the equivalent of tv_add applied to the offset to make sure that
signed ints are permitted (otherwise it depends on how timeval is
defined).

This is significantly more reliable than the previous model as the
global time should move in a much smoother way, and not according
to what thread last updated it, and the thread-local time should
always be very close to the global one.

Note that (at least for debugging) a cheap way to measure processing
lag would consist in measuring the difference between global_now_ms
and now_ms, as long as other threads keep it up-to-date.

4 years agoMINOR: time: change the global timeval and the the global tick at once
Willy Tarreau [Sun, 11 Apr 2021 13:34:25 +0000 (15:34 +0200)] 
MINOR: time: change the global timeval and the the global tick at once

Instead of using two CAS loops, better compute the two units
simultaneously and update them at once. There is no guarantee that
the update will be synchronous, but we don't care, what matters is
that both are monotonically updated and that global_now_ms always
follows the last known value of global_now.

4 years agoMINOR: time: remove useless variable copies in tv_update_date()
Willy Tarreau [Sun, 11 Apr 2021 13:17:48 +0000 (15:17 +0200)] 
MINOR: time: remove useless variable copies in tv_update_date()

In the global_now loop, we used to set tmp_adj from adjusted, then
set update it from tmp_now, then set adjusted back to tmp_adj, and
finally set now from adjusted. This is a long and unneeded set of
moves resulting from years of code changes. Let's just set now
directly in the loop, stop using adjusted and remove tmp_adj.

4 years agoMINOR: time: move the time initialization out of tv_update_date()
Willy Tarreau [Sun, 11 Apr 2021 13:00:34 +0000 (15:00 +0200)] 
MINOR: time: move the time initialization out of tv_update_date()

The time initialization was made a bit complex because we rely on a
dummy negative argument to reset all fields, leaving no distinction
between process-level initialization and thread-level initialization.
This patch changes this by introducing two functions, one for the
process and the second one for the threads. This removes ambigous
test and makes sure that the relevant fields are always initialized
exactly once. This also offers a better solution to the bug fixed in
commit b48e7c001 ("BUG/MEDIUM: time: make sure to always initialize
the global tick") as there is no more special values for global_now_ms.

It's simple enough to be backported if any other time-related issues
are encountered in stable versions in the future.

4 years agoCLEANUP: time: remove the now unused ms_left_scaled
Willy Tarreau [Sat, 10 Apr 2021 23:40:13 +0000 (01:40 +0200)] 
CLEANUP: time: remove the now unused ms_left_scaled

It was only used by freq_ctr and is not used anymore. In addition the
local curr_sec_ms was removed, as well as the equivalent extern
definitions which did not exist anymore either.

4 years agoMINOR: freq_ctr: simplify and improve the update function
Willy Tarreau [Sun, 11 Apr 2021 11:51:58 +0000 (13:51 +0200)] 
MINOR: freq_ctr: simplify and improve the update function

update_freq_ctr_period() was still not very clean and didn't wait for
the rotation lock to be dropped before trying again, thus maintaining
the contention at a high level. In addition, the rotation update was
made in three steps, which are not very efficient in terms of bus
cycles.

Here the wait loop was reworked so that the fast path remains short
and that the contended path waits for the lock to be dropped before
attempting another write, but it only waits a relax cycle before
attempting a read. The rotation block was simplified to remove a
test that was already validated by the first loop, and so that the
retrieval of the current period, its reset and its increment are all
performed in a single atomic op and the store to the previous period
is performed immediately after.

All this results in significantly smaller code for the inline function
(~1kB total) and a shorter critical path.

4 years agoMINOR: freq_ctr: add cpu_relax in the rotation loop of update_freq_ctr_period()
Willy Tarreau [Sat, 10 Apr 2021 23:18:39 +0000 (01:18 +0200)] 
MINOR: freq_ctr: add cpu_relax in the rotation loop of update_freq_ctr_period()

When counters are rotated, there is contention between the threads which
can slow down the operation of the thread performing the rotation. Let's
apply a cpu_relax there to let the first thread finish faster.

4 years agoMEDIUM: freq_ctr: replace the per-second counters with the generic ones
Willy Tarreau [Sat, 10 Apr 2021 21:41:25 +0000 (23:41 +0200)] 
MEDIUM: freq_ctr: replace the per-second counters with the generic ones

It remains cumbersome to preserve two versions of the freq counters and
two different internal clocks just for this. In addition, the savings
from using two different mechanisms are not that important as the only
saving is a divide that is replaced by a multiply, but now thanks to
the freq_ctr_total() unificaiton the code could also be simplified to
optimize it in case of constants.

This patch turns all non-period freq_ctr functions to static inlines
which call the period-based ones with a period of 1 second. A direct
benefit is that a single internal clock is now needed for any counter
and that they now all rely on ticks.

These 1-second counters are essentially used to report request rates
and to enforce a connection rate limitation in listeners. It was
verified that these continue to work like before.

4 years agoMINOR: freq_ctr: unify freq_ctr and freq_ctr_period into freq_ctr
Willy Tarreau [Sat, 10 Apr 2021 21:00:53 +0000 (23:00 +0200)] 
MINOR: freq_ctr: unify freq_ctr and freq_ctr_period into freq_ctr

Both structures are identical except the name of the field starting
the period and its description. Let's call them all freq_ctr and the
period's start "curr_tick" which is generic.

This is only a temporary change and fields are expected to remain
the same with no code change (verified).

4 years agoMINOR: freq_ctr: add the missing next_event_delay_period()
Willy Tarreau [Sat, 10 Apr 2021 21:36:07 +0000 (23:36 +0200)] 
MINOR: freq_ctr: add the missing next_event_delay_period()

There was still no function to compute a wait time for periods, let's
implement it on top of freq_ctr_total() as we'll soon need it for the
per-second one. The divide here is applied on the frequency so that it
will be replaced with a reciprocal multiply when constant.

4 years agoMEDIUM: freq_ctr: reimplement freq_ctr_remain_period() from freq_ctr_total()
Willy Tarreau [Sun, 11 Apr 2021 08:42:28 +0000 (10:42 +0200)] 
MEDIUM: freq_ctr: reimplement freq_ctr_remain_period() from freq_ctr_total()

Now the function becomes an inline one and only contains a divide and
a max. The divide will automatically go away with constant periods.

4 years agoMEDIUM: freq_ctr: make read_freq_ctr_period() use freq_ctr_total()
Willy Tarreau [Sat, 10 Apr 2021 22:57:33 +0000 (00:57 +0200)] 
MEDIUM: freq_ctr: make read_freq_ctr_period() use freq_ctr_total()

This one is the easiest to implement, it just requires a call and a
divide of the result. Anti-flapping correction for low-rates was
preserved.

Now calls using a constant period will be able to use a reciprocal
multiply for the period instead of a divide.

4 years agoMINOR: freq_ctr: add a generic function to report the total value
Willy Tarreau [Sat, 10 Apr 2021 22:38:06 +0000 (00:38 +0200)] 
MINOR: freq_ctr: add a generic function to report the total value

Most of the functions designed to read a counter over a period go through
the same complex loop and only differ in the way they use the returned
values, so it was worth implementing all this into freq_ctr_total() which
returns the total number of events over a period so that the caller can
finish its operation using a divide or a remaining time calculation. As
a special case, read_freq_ctr_period() doesn't take pending events but
requires to enable an anti-flapping correction at very low frequencies.
Thus the function implements it when pend<0.

Thanks to this function it will be possible to reimplement the other ones
as inline and merge the per-second ones with the arbitrary period ones
without always adding the cost of a 64 bit divide.

4 years agoMINOR: trace: make trace sources read_mostly
Willy Tarreau [Sat, 10 Apr 2021 17:29:26 +0000 (19:29 +0200)] 
MINOR: trace: make trace sources read_mostly

The trace sources are checked at plenty of places in the code and their
contents only change when trace status changes, let's mark them read_mostly.

4 years agoMINOR: pattern: make the pat_lru_seed read_mostly
Willy Tarreau [Sat, 10 Apr 2021 15:42:04 +0000 (17:42 +0200)] 
MINOR: pattern: make the pat_lru_seed read_mostly

This seed is created once at boot and is used in every LRU hash when
caching results. Let's mark it read_mostly.

4 years agoMINOR: protocol: move __protocol_by_family to read_mostly
Willy Tarreau [Sat, 10 Apr 2021 15:38:05 +0000 (17:38 +0200)] 
MINOR: protocol: move __protocol_by_family to read_mostly

This one is used for each outgoing connection and never changes after
boot, move it to read_mostly.

4 years agoMINOR: server: move idle_conn_task to read_mostly
Willy Tarreau [Sat, 10 Apr 2021 15:33:15 +0000 (17:33 +0200)] 
MINOR: server: move idle_conn_task to read_mostly

This pointer is used when adding connections to the idle list and is
never changed, let's move it to the read_mostly section.

4 years agoMINOR: threads: mark all_threads_mask as read_mostly
Willy Tarreau [Sat, 10 Apr 2021 15:28:18 +0000 (17:28 +0200)] 
MINOR: threads: mark all_threads_mask as read_mostly

This variable almost never changes and is read a lot in time-critical
sections. threads_want_rdv_mask is read very often as well in
thread_harmless_end() and is almost never changed (only when someone
uses thread_isolate()). Let's move both to read_mostly.

4 years agoMINOR: pool: move pool declarations to read_mostly
Willy Tarreau [Sat, 10 Apr 2021 15:23:00 +0000 (17:23 +0200)] 
MINOR: pool: move pool declarations to read_mostly

All pool heads are accessed via a pointer and should not be shared with
highly written variables. Move them to the read_mostly section.

4 years agoMINOR: kqueue: move kqueue_fd to read_mostly
Willy Tarreau [Sat, 10 Apr 2021 15:09:53 +0000 (17:09 +0200)] 
MINOR: kqueue: move kqueue_fd to read_mostly

This one only contains the list of per-thread kqueue FDs, and is used
a lot during updates. Let's mark it read_mostly to avoid false sharing
of FDs placed at the extremities.

4 years agoMINOR: epoll: move epoll_fd to read_mostly
Willy Tarreau [Sat, 10 Apr 2021 15:06:40 +0000 (17:06 +0200)] 
MINOR: epoll: move epoll_fd to read_mostly

This one only contains the list of per-thread epoll FDs, and is used
a lot during updates. Let's mark it read_mostly to avoid false sharing
of FDs placed at the extremities.

4 years agoMINOR: fd: move a few read-mostly variables to their own section
Willy Tarreau [Sat, 10 Apr 2021 14:58:13 +0000 (16:58 +0200)] 
MINOR: fd: move a few read-mostly variables to their own section

Some pointer to arrays such as fdtab, fdinfo, polled_mask etc are never
written to at run time but are used a lot. fdtab accesses appear a lot in
perf top because ha_used_fds is in the same cache line and is modified
all the time. This patch moves all these read-mostly variables to the
read_mostly section when defined. This way their cache lines will be
able to remain in shared state in all CPU caches.

4 years agoMINOR: global: declare a read_mostly section
Willy Tarreau [Sat, 10 Apr 2021 14:53:05 +0000 (16:53 +0200)] 
MINOR: global: declare a read_mostly section

Some variables are mostly read (mostly pointers) but they tend to be
merged with other ones in the same cache line, slowing their access down
in multi-thread setups. This patch declares an empty, aligned variable
in a section called "read_mostly". This will force a cache-line alignment
on this section so that any variable declared in it will be certain to
avoid false sharing with other ones. The section will be eliminated at
link time if not used.

A __read_mostly attribute was added to compiler.h to ease use of this
section.

4 years agoCLEANUP: initcall: rely on HA_SECTION_* instead of defining its own
Willy Tarreau [Sat, 10 Apr 2021 14:02:20 +0000 (16:02 +0200)] 
CLEANUP: initcall: rely on HA_SECTION_* instead of defining its own

Now initcalls are defined using the regular section definitions from
compiler.h in order to ease maintenance.

4 years agoMINOR: compiler: add macros to declare section names
Willy Tarreau [Sat, 10 Apr 2021 13:53:45 +0000 (15:53 +0200)] 
MINOR: compiler: add macros to declare section names

HA_SECTION() is used as an attribute to force a section name. This is
required because OSX prepends "__DATA, " in front of the declaration.
HA_SECTION_START() and HA_SECTION_STOP() are used as post-attribute on
variable declaration to designate the section start/end (needed only on
OSX, empty on others).

For platforms with an obsolete linker, all macros are left empty. It would
possibly still work on some of them but this will not be needed anyway.

4 years agoCLEANUP: initcall: rename HA_SECTION to HA_INIT_SECTION
Willy Tarreau [Sat, 10 Apr 2021 13:17:21 +0000 (15:17 +0200)] 
CLEANUP: initcall: rename HA_SECTION to HA_INIT_SECTION

The HA_SECTION name is too generic and will be reused globally. Let's
rename this one.

4 years agoMINOR: initcall: uniformize the section names between MacOS and other unixes
Willy Tarreau [Sat, 10 Apr 2021 13:43:17 +0000 (15:43 +0200)] 
MINOR: initcall: uniformize the section names between MacOS and other unixes

Due to length restrictions on OSX the initcall sections are called "i_"
there while they're called "init_" on other OSes. However the start and
end of sections are still called "__start_init_" and "__stop_init_",
which forces to have distinct code between the OSes. Let's switch everyone
to "i_" and rename the symbols accordingly.

4 years agoMINOR: trace: replace the trace() inline function with an equivalent macro
Willy Tarreau [Sat, 10 Apr 2021 17:20:01 +0000 (19:20 +0200)] 
MINOR: trace: replace the trace() inline function with an equivalent macro

The trace() function is convenient to avoid calling trace() when traces
are not enabled, but there starts to be some callers which place complex
expressions in their trace calls, which results in all of them to be
evaluated before being passed as arguments to the trace() function. This
needlessly wastes precious CPU cycles.

Let's change the function for a macro, so that the arguments are now only
evaluated when the surce has traces enabled. However having a generic
macro being called "trace()" can easily cause conflicts with innocent
code so we rename it "_trace".

Just doing this has resulted in a 2.5% increase of the HTTP/1 request rate.

4 years agoCLEANUP: pattern: make all pattern tables read-only
Willy Tarreau [Sat, 10 Apr 2021 15:44:27 +0000 (17:44 +0200)] 
CLEANUP: pattern: make all pattern tables read-only

Interestingly, all arrays used to declare patterns were read-write while
only hard-coded. Let's mark them const so that they move from data to
rodata and don't risk to experience false sharing.

4 years agoCI: travis: Drastically clean up .travis.yml
Tim Duesterhus [Fri, 9 Apr 2021 18:21:35 +0000 (20:21 +0200)] 
CI: travis: Drastically clean up .travis.yml

Now travis should only run on cron, on non-amd64, with a configuration that
only has the standard features enabled. This should reduce the number of
valuable build minutes consumed while providing as much value as possible.

4 years agoBUG/MINOR: mux-pt: Fix a possible UAF because of traces in mux_pt_io_cb
Christopher Faulet [Sat, 10 Apr 2021 07:02:32 +0000 (09:02 +0200)] 
BUG/MINOR: mux-pt: Fix a possible UAF because of traces in mux_pt_io_cb

In mux_pt_io_cb(), if a connection error or a shutdown is detected, the mux
is destroyed. Thus we must be careful to not use it in a trace message once
destroyed.

No backport needed. This patch should fix the issue #1220.

4 years agoMINOIR: mux-pt/trace: Register a new trace source with its events
Christopher Faulet [Thu, 8 Apr 2021 14:45:11 +0000 (16:45 +0200)] 
MINOIR: mux-pt/trace: Register a new trace source with its events

As for the other muxes, traces are now supported in the pt mux. All parts of
the multiplexer is covered by these traces. Events are splitted by
categories (connection, stream, rx and tx).

In traces, the first argument is always a connection. So it is easy to get
the mux context (conn->ctx). The second argument is always a conn-stream and
mau be NUUL. The third one is a buffer and it may also be NULL. Depending on
the context it is the request or the response. In all cases it is owned by a
channel. Finally, the fourth argument is an integer value. Its meaning
depends on the calling context.

4 years ago[RELEASE] Released version 2.4-dev16 v2.4-dev16
Willy Tarreau [Fri, 9 Apr 2021 15:10:39 +0000 (17:10 +0200)] 
[RELEASE] Released version 2.4-dev16

Released version 2.4-dev16 with the following main changes :
    - CLEANUP: dev/flags: remove useless test in the stdin number parser
    - MINOR: No longer rely on deprecated sample fetches for predefined ACLs
    - MINOR: acl: Add HTTP_2.0 predefined macro
    - BUG/MINOR: hlua: Detect end of request when reading data for an HTTP applet
    - BUG/MINOR: tools: fix parsing "us" unit for timers
    - MINOR: server/bind: add support of new prefixes for addresses.
    - MINOR: log: register config file and line number on log servers.
    - MEDIUM: log: support tcp or stream addresses on log lines.
    - BUG/MEDIUM: log: fix config parse error logging on stdout/stderr or any raw fd
    - CLEANUP: fd: remove FD_POLL_DATA and FD_POLL_STICKY
    - MEDIUM: fd: prepare FD_POLL_* to move to bits 8-15
    - MEDIUM: fd: merge fdtab[].ev and state for FD_EV_* and FD_POLL_* into state
    - MINOR: fd: move .linger_risk into fdtab[].state
    - MINOR: fd: move .cloned into fdtab[].state
    - MINOR: fd: move .initialized into fdtab[].state
    - MINOR: fd: move .et_possible into fdtab[].state
    - MINOR: fd: move .exported into fdtab[].state
    - MINOR: fd: implement an exclusive syscall bit to remove the ugly "log" lock
    - MINOR: cli/show-fd: slightly reorganize the FD status flags
    - MINOR: atomic/arm64: detect and use builtins for the double-word CAS
    - CLEANUP: atomic: add an explicit _FETCH variant for add/sub/and/or
    - CLEANUP: atomic: make all standard add/or/and/sub operations return void
    - CLEANUP: atomic: add a fetch-and-xxx variant for common operations
    - CLEANUP: atomic: add HA_ATOMIC_INC/DEC for unit increments
    - CLEANUP: atomic/tree-wide: replace single increments/decrements with inc/dec
    - CLEANUP: atomic: use the __atomic variant of BTS/BTR on modern compilers
    - MINOR: atomic: implement native BTS/BTR for x86
    - MINOR: ist: Add `istappend(struct ist, char)`
    - MINOR: ist: Add `istshift(struct ist*)`
    - MINOR: ist: Add `istsplit(struct ist*, char)`
    - BUG/MAJOR: fd: switch temp values to uint in fd_stop_both()
    - MINOR: opentracing: register config file and line number on log servers
    - MEDIUM: resolvers: add support of tcp address on nameserver line.
    - MINOR: ist: Rename istappend() to __istappend()
    - CLEANUP: htx: Make http_get_stline take a `const struct`
    - CLEANUP: ist: Remove unused `count` argument from `ist2str*`
    - CLEANUP: Remove useless malloc() casts

4 years agoCLEANUP: Remove useless malloc() casts
Tim Duesterhus [Thu, 8 Apr 2021 18:05:23 +0000 (20:05 +0200)] 
CLEANUP: Remove useless malloc() casts

This is not C++.

4 years agoCLEANUP: ist: Remove unused `count` argument from `ist2str*`
Tim Duesterhus [Sat, 3 Apr 2021 18:39:21 +0000 (20:39 +0200)] 
CLEANUP: ist: Remove unused `count` argument from `ist2str*`

This argument is not being used inside the function (and the functions
themselves are unused as well) and not documented. Its purpose is not clear.
Just remove it.

4 years agoCLEANUP: htx: Make http_get_stline take a `const struct`
Tim Duesterhus [Sat, 3 Apr 2021 18:39:20 +0000 (20:39 +0200)] 
CLEANUP: htx: Make http_get_stline take a `const struct`

Nothing is being modified there, so this can be `const`.

4 years agoMINOR: ist: Rename istappend() to __istappend()
Tim Duesterhus [Thu, 8 Apr 2021 17:28:16 +0000 (19:28 +0200)] 
MINOR: ist: Rename istappend() to __istappend()

Indicate that this function is not inherently safe by adding two underscores as
a prefix.

4 years agoMEDIUM: resolvers: add support of tcp address on nameserver line.
Emeric Brun [Wed, 7 Apr 2021 14:04:54 +0000 (16:04 +0200)] 
MEDIUM: resolvers: add support of tcp address on nameserver line.

This patch re-works configuration parsing, it removes the "server"
lines from "resolvers" sections introduced in commit 56fc5d9eb:
MEDIUM: resolvers: add supports of TCP nameservers in resolvers.

It also extends the nameserver lines to support stream server
addresses such as:

resolvers
  nameserver localhost tcp@127.0.0.1:53

Doing so, a part of nameserver's init code was factorized in
function 'parse_resolvers' and removed from 'post_parse_resolvers'.

4 years agoMINOR: opentracing: register config file and line number on log servers
Miroslav Zagorac [Wed, 7 Apr 2021 09:14:23 +0000 (11:14 +0200)] 
MINOR: opentracing: register config file and line number on log servers

In commit 9533a7038 new parameters have been added to the declaration
of function parse_logsrv().

This patch should be backported to all branches where the OpenTracing
filter is located.

4 years agoBUG/MAJOR: fd: switch temp values to uint in fd_stop_both()
Willy Tarreau [Wed, 7 Apr 2021 18:46:26 +0000 (20:46 +0200)] 
BUG/MAJOR: fd: switch temp values to uint in fd_stop_both()

With latest commit f50906519 ("MEDIUM: fd: merge fdtab[].ev and state
for FD_EV_* and FD_POLL_* into state") one occurrence of a pair of
chars was missed in fd_stop_both(), resulting in the operation to
fail if the upper flags were set. Interestingly it managed to fail
2 tests in all setups in the CI while all used to work fine on my
local machines. Probably that the reason is that the chars had enough
room above them for the CAS to fail then refill "old" overwriting the
upper parts of the stack, and that thanks to this the subsequent tests
worked. With ASAN being used on lots of tests, it very likely caught
it but used to only report failed tests with no more info.

No backport is needed, as this was never released nor backported.

4 years agoMINOR: ist: Add `istsplit(struct ist*, char)`
Tim Duesterhus [Mon, 5 Apr 2021 15:53:56 +0000 (17:53 +0200)] 
MINOR: ist: Add `istsplit(struct ist*, char)`

istsplit is a combination of iststop + istadv.

4 years agoMINOR: ist: Add `istshift(struct ist*)`
Tim Duesterhus [Mon, 5 Apr 2021 15:53:55 +0000 (17:53 +0200)] 
MINOR: ist: Add `istshift(struct ist*)`

istshift() returns the first character and advances the ist by 1.

4 years agoMINOR: ist: Add `istappend(struct ist, char)`
Tim Duesterhus [Mon, 5 Apr 2021 15:53:54 +0000 (17:53 +0200)] 
MINOR: ist: Add `istappend(struct ist, char)`

This function appends the given char to the given `ist` and returns
the resulting `ist`.

4 years agoMINOR: atomic: implement native BTS/BTR for x86
Willy Tarreau [Tue, 6 Apr 2021 12:24:51 +0000 (14:24 +0200)] 
MINOR: atomic: implement native BTS/BTR for x86

The current BTS/BTR operations on x86 are ugly because they rely on a
CAS, so they may be unfair and take time to converge. Fortunately,
where they are currently used (mostly FDs) the contention is expected
to be rare (mostly listeners). But this also limits their use to such
few low-load cases.

On x86 there is a set of BTS/BTR instructions which help for this,
but before the FD's state migrated to 32 bits there was little use of
them since they do not exist in 8 bits.

Now at least it makes sense to use them, at the very least in order
to significantly reduce the code size (one BTS instead of a CMPXCHG
loop). The implementation relies on modern gcc's ability to return
condition flags and limit code inflation and register spilling. The
fall back is retained on the old implementation for all other situations
(inappropriate target size or non-capable compiler). The code shrank
by 1.6 kB on the fast path.

As expected, for now on up to 4 threads there is no measurable difference
of performance.

4 years agoCLEANUP: atomic: use the __atomic variant of BTS/BTR on modern compilers
Willy Tarreau [Tue, 6 Apr 2021 12:04:22 +0000 (14:04 +0200)] 
CLEANUP: atomic: use the __atomic variant of BTS/BTR on modern compilers

Probably due to the result of an old copy-paste, HA_ATOMIC_BTS/BTR were
still implemented using the __sync_*  builtins instead of the more
modern __atomic_* which allow to specify the memory model. Let's update
this to use the newer there and also implement the relaxed variants
(which are not used for now).

4 years agoCLEANUP: atomic/tree-wide: replace single increments/decrements with inc/dec
Willy Tarreau [Tue, 6 Apr 2021 11:53:36 +0000 (13:53 +0200)] 
CLEANUP: atomic/tree-wide: replace single increments/decrements with inc/dec

This patch replaces roughly all occurrences of an HA_ATOMIC_ADD(&foo, 1)
or HA_ATOMIC_SUB(&foo, 1) with the equivalent HA_ATOMIC_INC(&foo) and
HA_ATOMIC_DEC(&foo) respectively. These are 507 changes over 45 files.

4 years agoCLEANUP: atomic: add HA_ATOMIC_INC/DEC for unit increments
Willy Tarreau [Tue, 6 Apr 2021 10:11:04 +0000 (12:11 +0200)] 
CLEANUP: atomic: add HA_ATOMIC_INC/DEC for unit increments

Most ADD/SUB callers use them for a single unit (e.g. refcounts) and
it's a pain to always pass ",1". Let's add them to simplify the API.
However we currently don't add any return value. If needed in the future
better report zero/non-zero than a real value for the sake of efficiency
at the instruction level.

4 years agoCLEANUP: atomic: add a fetch-and-xxx variant for common operations
Willy Tarreau [Tue, 6 Apr 2021 09:57:41 +0000 (11:57 +0200)] 
CLEANUP: atomic: add a fetch-and-xxx variant for common operations

The fetch_and_xxx variant is often missing for add/sub/and/or. In fact
it was only provided for ADD under the name XADD which corresponds to
the x86 instruction name. But for destructive operations like AND and
OR it's missing even more as it's not possible to know the value before
modifying it.

This patch explicitly adds HA_ATOMIC_FETCH_{OR,AND,ADD,SUB} which
cover these standard operations, and renames XADD to FETCH_ADD (there
were only 6 call places).

In the future, backport of fixes involving such operations could simply
remap FETCH_ADD(x) to XADD(x), FETCH_SUB(x) to XADD(-x), and for the
OR/AND if needed, these could possibly be done using BTS/BTR.

It's worth noting that xchg could have been renamed to fetch_and_store()
but xchg already has well understood semantics and it wasn't needed to
go further.

4 years agoCLEANUP: atomic: make all standard add/or/and/sub operations return void
Willy Tarreau [Tue, 6 Apr 2021 09:46:58 +0000 (11:46 +0200)] 
CLEANUP: atomic: make all standard add/or/and/sub operations return void

In order to make sure these ones will not be used anymore in an expression,
let's make them always void. New callers will now be forced to use the
explicit _FETCH variant if required.

4 years agoCLEANUP: atomic: add an explicit _FETCH variant for add/sub/and/or
Willy Tarreau [Tue, 6 Apr 2021 09:44:07 +0000 (11:44 +0200)] 
CLEANUP: atomic: add an explicit _FETCH variant for add/sub/and/or

Currently our atomic ops return a value but it's never known whether
the fetch is done before or after the operation, which causes some
confusion each time the value is desired. Let's create an explicit
variant of these operations suffixed with _FETCH to explicitly mention
that the fetch occurs after the operation, and make use of it at the
few call places.

4 years agoMINOR: atomic/arm64: detect and use builtins for the double-word CAS
Willy Tarreau [Tue, 6 Apr 2021 07:21:33 +0000 (09:21 +0200)] 
MINOR: atomic/arm64: detect and use builtins for the double-word CAS

Gcc 10.2 implements outline atomics on aarch64. The replace all inline
atomic ops with a function call that checks if the machine supports LSE
atomics. This comes with a small cost but allows modern machines to scale
much better than with the old LL/SC ones even when built for full 8.0
compatibility.

This patch enables the use of the __atomic_compare_exchange() builtin
for the double-word CAS when detected as available instead of using the
hand-written LL/SC version. The extra cost is negligible because we do
very few DWCAS operations (essentially FD migrations and shared pools)
so the cost is low but under high contention it can still be beneficial.
As expected no performance difference was measured in either direction
on 4-core machines with this change.

This could be backported to 2.3 if it was shown that FD migrations were
representing a significant source of contention, but for now it does
not appear to be needed.

4 years agoMINOR: cli/show-fd: slightly reorganize the FD status flags
Willy Tarreau [Wed, 7 Apr 2021 06:48:12 +0000 (08:48 +0200)] 
MINOR: cli/show-fd: slightly reorganize the FD status flags

Slightly reorder the status flags to better match their order in the
"state" field, and also decode the "shut" state which is particularly
useful and already part of this field.

4 years agoMINOR: fd: implement an exclusive syscall bit to remove the ugly "log" lock
Willy Tarreau [Wed, 7 Apr 2021 15:36:57 +0000 (17:36 +0200)] 
MINOR: fd: implement an exclusive syscall bit to remove the ugly "log" lock

There is a function called fd_write_frag_line() that's essentially used
by loggers and that is used to write an atomic message line over a file
descriptor using writev(). However a lock is required around the writev()
call to prevent messages from multiple threads from being interleaved.
Till now a SPIN_TRYLOCK was used on a dedicated lock that was common to
all FDs. This is quite not pretty as if there are multiple output pipes
to collect logs, there will be quite some contention. Now that there
are empty flags left in the FD state and that we can finally use atomic
ops on them, let's add a flag to indicate the FD is locked for exclusive
access by a syscall. At least the locking will now be on an FD basis and
not the whole process, so we can remove the log_lock.

4 years agoMINOR: fd: move .exported into fdtab[].state
Willy Tarreau [Tue, 6 Apr 2021 16:09:06 +0000 (18:09 +0200)] 
MINOR: fd: move .exported into fdtab[].state

No need to keep this flag apart any more, let's merge it into the global
state.

4 years agoMINOR: fd: move .et_possible into fdtab[].state
Willy Tarreau [Tue, 6 Apr 2021 16:05:48 +0000 (18:05 +0200)] 
MINOR: fd: move .et_possible into fdtab[].state

No need to keep this flag apart any more, let's merge it into the global
state.

4 years agoMINOR: fd: move .initialized into fdtab[].state
Willy Tarreau [Tue, 6 Apr 2021 15:57:12 +0000 (17:57 +0200)] 
MINOR: fd: move .initialized into fdtab[].state

No need to keep this flag apart any more, let's merge it into the global
state. The bit was not cleared in fd_insert() because the only user is
the function used to create and atomically send a log message to a pipe
FD, which never registers the fd. Here we clear it nevertheless for the
sake of clarity.

Note that with an extra cleaning pass we could have a bit number
here and simply use a BTS to test and set it.

4 years agoMINOR: fd: move .cloned into fdtab[].state
Willy Tarreau [Tue, 6 Apr 2021 15:53:33 +0000 (17:53 +0200)] 
MINOR: fd: move .cloned into fdtab[].state

No need to keep this flag apart any more, let's merge it into the global
state.

4 years agoMINOR: fd: move .linger_risk into fdtab[].state
Willy Tarreau [Tue, 6 Apr 2021 15:49:19 +0000 (17:49 +0200)] 
MINOR: fd: move .linger_risk into fdtab[].state

No need to keep this flag apart any more, let's merge it into the global
state. The CLI's output state was extended to 6 digits and the linger/cloned
flags moved inside the parenthesis.

4 years agoMEDIUM: fd: merge fdtab[].ev and state for FD_EV_* and FD_POLL_* into state
Willy Tarreau [Tue, 6 Apr 2021 15:23:40 +0000 (17:23 +0200)] 
MEDIUM: fd: merge fdtab[].ev and state for FD_EV_* and FD_POLL_* into state

For a long time we've had fdtab[].ev and fdtab[].state which contain two
arbitrary sets of information, one is mostly the configuration plus some
shutdown reports and the other one is the latest polling status report
which also contains some sticky error and shutdown reports.

These ones used to be stored into distinct chars, complicating certain
operations and not even allowing to clearly see concurrent accesses (e.g.
fd_delete_orphan() would set the state to zero while fd_insert() would
only set the event to zero).

This patch creates a single uint with the two sets in it, still delimited
at the byte level for better readability. The original FD_EV_* values
remained at the lowest bit levels as they are also known by their bit
value. The next step will consist in merging the remaining bits into it.

The whole bits are now cleared both in fd_insert() and _fd_delete_orphan()
because after a complete check, it is certain that in both cases these
functions are the only ones touching these areas. Indeed, for
_fd_delete_orphan(), the thread_mask has already been zeroed before a
poller can call fd_update_event() which would touch the state, so it
is certain that _fd_delete_orphan() is alone. Regarding fd_insert(),
only one thread will get an FD at any moment, and it as this FD has
already been released by _fd_delete_orphan() by definition it is certain
that previous users have definitely stopped touching it.

Strictly speaking there's no need for clearing the state again in
fd_insert() but it's cheap and will remove some doubts during some
troubleshooting sessions.

4 years agoMEDIUM: fd: prepare FD_POLL_* to move to bits 8-15
Willy Tarreau [Tue, 6 Apr 2021 14:55:17 +0000 (16:55 +0200)] 
MEDIUM: fd: prepare FD_POLL_* to move to bits 8-15

In preparation of merging FD_POLL* and FD_EV*, this only changes the
value of FD_POLL_* to use bits 8-15 (the second byte). The size of the
field has been temporarily extended to 32 bits already, as well as
the temporary variables that carry the new composite value inside
fd_update_events(). The resulting fdtab entry becomes temporarily
unaligned. All places making access to .ev or FD_POLL_* were carefully
inspected to make sure they were safe regarding this change. Only one
temporary update was needed for the "show fd" code. The code was only
slightly inflated at this step.

4 years agoCLEANUP: fd: remove FD_POLL_DATA and FD_POLL_STICKY
Willy Tarreau [Tue, 6 Apr 2021 14:48:02 +0000 (16:48 +0200)] 
CLEANUP: fd: remove FD_POLL_DATA and FD_POLL_STICKY

The former was not used and the second was used only as a positive mask
of the flags to keep instead of having the flags that are updated. Both
were removed in favor of a new FD_POLL_UPDT_MASK that only mentions the
updated flags. This will ease merging of state and ev later.

4 years agoBUG/MEDIUM: log: fix config parse error logging on stdout/stderr or any raw fd
Emeric Brun [Wed, 7 Apr 2021 12:26:44 +0000 (14:26 +0200)] 
BUG/MEDIUM: log: fix config parse error logging on stdout/stderr or any raw fd

The regression was introduced by commit previous commit 94aab06:
MEDIUM: log: support tcp or stream addresses on log lines.

This previous patch tries to retrieve the used protocol parsing
the address using the str2sa_range function but forgets that
the raw file descriptor adresses don't specify a protocol
and str2sa_range probes an error.

This patch re-work the str2sa_range function to stop
probing error if an authorized RAW_FD address is parsed
whereas the caller request also a protocol.

It also modify the code of parse_logsrv to switch on stream
logservers only if a protocol was detected.

4 years agoMEDIUM: log: support tcp or stream addresses on log lines.
Emeric Brun [Fri, 2 Apr 2021 08:41:36 +0000 (10:41 +0200)] 
MEDIUM: log: support tcp or stream addresses on log lines.

An explicit stream address prefix such as "tcp6@" "tcp4@"
"stream+ipv6@" "stream+ipv4@" or "stream+unix@" will
allocate an implicit ring buffer with a forward server
targeting the given address.

This is usefull to simply send logs to a log server in tcp
and It doesn't need to declare a ring section in configuration.