Commit Graph

8210 Commits

Author SHA1 Message Date
William Lallemand
550db6d188 MEDIUM: mworker: does not create the CLI proxy when no listener
Does not create the CLI proxy if no -S argument was specified. It
prevents a warning that says that the MASTER proxy does not have any
bind option.
2018-11-06 18:28:33 +01:00
William Lallemand
6b7cd0a72b MINOR: cli: can't connect to the target CLI
Return an error and quit if the CLI proxy is not able to connect to a
target.
2018-11-06 18:28:33 +01:00
William Lallemand
adbce8e0dd MINOR: cli: show the number of reload in 'show proc'
Displays the number of reload in the life of each worker.
2018-11-06 18:28:33 +01:00
Willy Tarreau
2d372c2aa1 MINOR: stats: report the number of currently connected peers
The active peers output indicates both the number of established peers
connections and the number of peers connection attempts. The new counter
"ConnectedPeers" also indicates the number of currently connected peers.
This helps detect that some peers cannot be reached for example. It's
worth mentioning that this value changes over time because unused peers
are often disconnected and reconnected. Most of the time it should be
equal to ActivePeers.
2018-11-05 17:15:21 +01:00
Willy Tarreau
199ad24661 MINOR: stats: report the number of active peers in "show info"
Peers are the last type of activity which can maintain a job present, so
it's important to report that such an entity is still active to explain
why the job count may be higher than zero. Here by "ActivePeers" we report
peers sessions, which include both established connections and outgoing
connection attempts.
2018-11-05 17:15:21 +01:00
Willy Tarreau
00098ea034 MINOR: stats: report the number of active jobs and listeners in "show info"
When an haproxy process doesn't stop after a reload, it's because it
still has some active "jobs", which mainly are active sessions, listeners,
peers or other specific activities. Sometimes it's difficult to troubleshoot
the cause of these issues (which generally are the result of a bug) only
because some indicators are missing.

This patch add the number of listeners, the number of jobs, and the stopping
status to the output of "show info". This way it becomes a bit easier to try
to narrow down the cause of such an issue should it happen. A typical use
case is to connect to the CLI before reloading, then issuing the "show info"
command to see what happens. In the normal situation, stopping should equal
1, jobs should equal 1 (meaning only the CLI is still active) and listeners
should equal zero.

The patch is so trivial that it could make sense to backport it to 1.8 in
order to help with troubleshooting.
2018-11-05 17:15:21 +01:00
Willy Tarreau
086735a688 BUG/MINOR: tasks: make sure wakeup events are properly reported to subscribers
The tasks API was changed in 1.9-dev1 with commit 9f6af3322 ("MINOR: tasks:
Change the task API so that the callback takes 3 arguments."), causing the
task's state not to be usable anymore and to have been replaced with an
explicit argument in the callee. The task's state doesn't contain any trace
of the wakeup cause anymore. But there were two places where the old task's
state remained in use :
  - sessions, used to more accurately report timeouts in logs when seeing
    TASK_WOKEN_TIMEOUT ;
  - peers, used to finish resynchronization when seeing TASK_WOKEN_SIGNAL

This commit fixes both occurrences by making sure we don't access task->state
directly (should we rename it by the way ?).

No backport is needed.
2018-11-05 17:15:21 +01:00
Willy Tarreau
1d0b7069f2 BUG/MAJOR: stream-int: don't call si_cs_recv() in stream_int_chk_rcv_conn()
This one causes some events to be lost. It has already been tested in
an experimental branch but was not merged until being certain it was
needed. Fred figured that requesting /?k=1&s=447392 from httpterm through
haproxy-master was enough to stall the transfer.

No backport is needed, this only affects 1.9-dev5.
2018-10-30 11:05:24 +01:00
Cyril Bonté
6c81d5f41a DOC: split the http-response actions in their own section
Similarly to the "http-request" actions, this is an attempt to make the
documentation easier to read.
2018-10-30 04:16:32 +01:00
Cyril Bonté
c6ad23bbe7 DOC: split the http-request actions in their own section
Since http-request was first introduced, more and more actions have been
added over time. This makes the "http-request" difficult to read and some
actions were forgotten in the list.

This is an attempt to make the documenation cleaner. In future steps, it
would be great to provide at least one example for each action.
2018-10-30 04:15:29 +01:00
Willy Tarreau
943e7ec025 MEDIUM: auth/threads: make use of crypt_r() on systems supporting it
On systems where crypt_r() is available, prefer it over a locked crypt().
This improves performance especially on very slow crypto algorithms.
2018-10-29 19:17:39 +01:00
Willy Tarreau
4698adf68f MINOR: compat: automatically detect support for crypt_r()
glibc >= 2.2 and FreeBSD >= 12.0 support crypt_r(), let's detect this
and set a macro HA_HAVE_CRYPT_R for this.
2018-10-29 19:14:14 +01:00
Willy Tarreau
34d4b525a1 BUG/MEDIUM: auth/threads: use of crypt() is not thread-safe
It was reported here that authentication may fail when threads are
enabled :

    https://bugzilla.redhat.com/show_bug.cgi?id=1643941

While I couldn't reproduce the issue, it's obvious that there is a
problem with the use of the non-reentrant crypt() function there.
On Linux systems there's crypt_r() but not on the vast majority of
other ones. Thus a first approach consists in placing a lock around
this crypt() call. Another patch may relax it when crypt_r() is
available.

This fix must be backported to 1.8. Thanks to Ryan O'Hara for the
quick notification.
2018-10-29 18:06:02 +01:00
William Lallemand
744de5b52a BUG/MINOR: cli: forward the whole command on master CLI
A bug occurs when the CLI proxy of the master received a command which
is prefixed by some spaces but without a routing prefix (@).
In this case the pcli_parse_request() was returning a wrong number of
data to forward.

The response analyzer was called twice and the prompt displayed twice.
2018-10-29 17:23:27 +01:00
Willy Tarreau
ce487aab46 BUG/MEDIUM: tools: fix direction of my_ffsl()
Commit 27346b01a ("OPTIM: tools: optimize my_ffsl() for x86_64") optimized
my_ffsl() for intensive use cases in the scheduler, but as half of the times
I got it wrong so it counted bits the reverse way. It doesn't matter for the
scheduler nor fd cache but it broke cpu-map with threads which heavily relies
on proper ordering.

We should probably consider dropping support for gcc < 3.4 and switching
to builtins for these ones, though often they are as ambiguous.

No backport is needed.
2018-10-29 16:09:57 +01:00
Willy Tarreau
bddf292cbd [RELEASE] Released version 1.9-dev5
Released version 1.9-dev5 with the following main changes :
    - BUILD: Makefile: add the new ERR variable to force -Werror
    - MINOR: freq_ctr: add swrate_add_scaled() to work with large samples
    - MINOR: stream_interface: Avoid calling si_cs_send/recv if not needed.
    - CLEANUP: http: Remove the unused function http_find_header
    - MINOR: h1: Export some functions parsing the value of some HTTP headers
    - BUG/MEDIUM: stream-int: don't set SI_FL_WAIT_ROOM on CF_READ_DONTWAIT
    - MINOR: proxy: add a new option "http-use-htx"
    - BUG/MEDIUM: pools: fix the minimum allocation size
    - MINOR: shctx: Shared objects block by block allocation.
    - MINOR: cache: Larger HTTP objects caching.
    - MINOR: shctx: Add a maximum object size parameter.
    - MINOR: cache: Add "max-object-size" option.
    - DOC: Update about the cache support for big objects.
    - BUG/MINOR: cache: Crashes with "total-max-size" > 2047(MB).
    - BUG/MINOR: cache: Wrong usage of shctx_init().
    - BUG/MINOR: ssl: Wrong usage of shctx_init().
    - MINOR: cache: Avoid usage of atoi() when parsing "max-object-size".
    - MINOR: shctx: Change max. object size type to unsigned int.
    - DOC: cache: Missing information about "total-max-size" and "max-object-size"
    - CLEANUP: tools: fix misleading comment above function LIM2A
    - MEDIUM: channel: merge back flags CF_WRITE_PARTIAL and CF_WRITE_EVENT
    - BUG/MINOR: only mark connections private if NTLM is detected
    - BUG/MINOR: only auto-prefer last server if lb-alg is non-deterministic
    - MINOR: stream: don't prune variables if the list is empty
    - MINOR: stream-int: add si_alloc_ibuf() to ease input buffer allocation
    - MEDIUM: stream-int: replace channel_alloc_buffer() with si_alloc_ibuf() everywhere
    - MEDIUM: stream: always call si_cs_recv() after a failed buffer allocation
    - MEDIUM: stream: don't try to send first in process_stream()
    - MEDIUM: stream-int: make si_update() synchronize flag changes before the I/O
    - MEDIUM: stream-int: call si_cs_process() in stream_int_update_conn
    - MINOR: stream-int: don't needlessly call tasklet_wakeup() in stream_int_chk_snd_conn()
    - MINOR: stream-int: make stream_int_notify() not wake the tasklet up
    - MINOR: stream-int: don't needlessly call si_cs_send() in si_cs_process()
    - MINOR: mworker: number of reload in the life of a worker
    - MEDIUM: mworker: each worker socketpair is a CLI listener
    - REORG: mworker: move struct mworker_proc to global.h
    - MINOR: server: export new_server() function
    - MEDIUM: mworker: move proc_list gen before proxies startup
    - MEDIUM: mworker: add proc_list in global.h
    - MEDIUM: mworker: proxy for the master CLI
    - MEDIUM: mworker: create CLI listeners from argv[]
    - MEDIUM: cli: disable some keywords in the master
    - MEDIUM: mworker: find the server ptr using a CLI prefix
    - MEDIUM: cli: 'show proc' displays processus
    - MEDIUM: cli: implement 'mode cli' proxy analyzers
    - MINOR: cli: displays sockpair@ in "show cli sockets"
    - MEDIUM: cli: enable "show cli sockets" for the master
    - MINOR: cli: put @master @<relative pid> @!<pid> in the help
    - MEDIUM: listeners: set O_CLOEXEC on the accepted FDs
    - MEDIUM: mworker: stop the master proxy in the workers
    - MEDIUM: channel: reorder the channel analyzers for the cli
    - MEDIUM: cli: write a prompt for the CLI proxy of the master
    - MINOR: cli: helper to write an response message and close
    - MINOR: cache: Add "Age" header.
    - REGTEST: make the IP+port logging test more reliable
    - BUG/MINOR: memory: make the thread-local cache allocator set the debugging link
    - BUG/MAJOR: http: http_txn_get_path() may deference an inexisting buffer
    - BUG/MINOR: backend: assign the wait list after the error check
2018-10-28 20:39:31 +01:00
Willy Tarreau
cde1bc64cb BUG/MINOR: backend: assign the wait list after the error check
Commit 85b73e9 ("BUG/MEDIUM: stream: Make sure polling is right on retry.")
introduced a possible null dereference on the error path detected by gcc-7.
Let's simply assign srv_conn after checking the error and not before.

No backport is needed.
2018-10-28 20:36:00 +01:00
Willy Tarreau
9d9ccdbf8b BUG/MAJOR: http: http_txn_get_path() may deference an inexisting buffer
When the "path" sample fetch function is called without any path, the
function doesn't check that the request buffer is allocated. While this
doesn't happen with the request during processing, it can definitely
happen when mistakenly trying to reference a path from the response
since the request channel is not allocated anymore.

It's certain that this bug was emphasized by the buffer changes that
went in 1.9 and the HTTP refactoring, but at first glance, 1.8 doesn't
seem 100% safe either so it's possible that older version are affected
as well.

Thanks to PiBa-NL for reporting this bug with a reproducer.
2018-10-28 20:16:12 +01:00
Willy Tarreau
8e9f4531cb BUG/MINOR: memory: make the thread-local cache allocator set the debugging link
When building with DEBUG_MEMORY_POOLS, an element returned from the
cache would not have its pool link initialized unless it's allocated
using pool_alloc(). This is problematic for buffer allocators which
use pool_alloc_dirty(), as freeing this object will make the code
think it was allocated from another pool. This patch does two things :
  - make __pool_get_from_cache() set the link
  - remove the extra initialization from pool_alloc() since it's always
    done in either __pool_get_first() or __pool_refill_alloc()

This patch is marked MINOR since it only affects code explicitly built
for debugging. No backport is needed.
2018-10-28 20:12:31 +01:00
Willy Tarreau
f95838ca2d REGTEST: make the IP+port logging test more reliable
On my machine, test log/b00000.vtc fails ~9/10 times. Apparently, the
connection is often marked as reset before the timeout strikes, so the
log shows "CD" flags instead of "cD". This fix does two things :
  1) shorten the client timeout to 1 millisecond instead of 5
  2) accept both "cD" and "CD" as valid termination states since the
     purpose is to validate the source address and port, and not the
     status itself.
2018-10-28 19:19:48 +01:00
Frédéric Lécaille
e7a770ce80 MINOR: cache: Add "Age" header.
This patch makes the cache capable of adding an "Age" header as defined by
rfc7234.

During the storage of new HTTP objects we memorize ->eoh value and
the value of the "Age" header coming from the origin server.
These information may then be reused to return the cached HTTP objects
with a new "Age" header.

May be backported to 1.8.
2018-10-28 19:06:59 +01:00
William Lallemand
deeaa593f3 MINOR: cli: helper to write an response message and close
pcli_reply_and_close() writes a message to the client and close the
connection. To be used only in the CLI proxy.
2018-10-28 14:13:35 +01:00
William Lallemand
2f4ce202d7 MEDIUM: cli: write a prompt for the CLI proxy of the master
Write a prompt with the PID of the target or master.
It's always activated for now.

Example:
    1234>
    master>
2018-10-28 14:13:34 +01:00
William Lallemand
90b1ca1ff5 MEDIUM: channel: reorder the channel analyzers for the cli
Reorder the channel analyzers so the CLI analyzers are defined before
the XFER_DATA ones.
2018-10-28 14:13:31 +01:00
William Lallemand
309dc9adec MEDIUM: mworker: stop the master proxy in the workers
The master proxy which handles the CLI should not be used or shown in
the stats of the workers. This proxy is now disabled after the fork.
2018-10-28 14:03:31 +01:00
William Lallemand
0b3e849a48 MEDIUM: listeners: set O_CLOEXEC on the accepted FDs
Set the O_CLOEXEC flag on the accept, useful to avoid an FD leak in the
master process, since it reexecutes itself during a reload
2018-10-28 14:03:31 +01:00
William Lallemand
4e8450b7d6 MINOR: cli: put @master @<relative pid> @!<pid> in the help
Add help for the prefix command of the CLI. These help only displays
from the CLI of the master.
2018-10-28 14:03:30 +01:00
William Lallemand
35851fbaf4 MEDIUM: cli: enable "show cli sockets" for the master
Enable the keyword on the master CLI.
2018-10-28 14:03:30 +01:00
William Lallemand
2631434b4b MINOR: cli: displays sockpair@ in "show cli sockets"
The 'show cli sockets' was not handling the sockpairs, it now displays
the fd of the socket and also show the unknown protocols.
2018-10-28 14:03:30 +01:00
William Lallemand
cf62f7e3cb MEDIUM: cli: implement 'mode cli' proxy analyzers
This patch implements analysers for parsing the CLI and extra features
for the master's CLI.

For each command (sent alone, or separated by ; or \n) the request
analyser will determine to which server it should send the request.

The 'mode cli' proxy is able to parse a prefix for each command which is
used to select the apropriate server. The prefix start by @ and is
followed by "master", the PID preceded by ! or the relative PID. (e.g.
@master, @1, @!1234). The servers are not round-robined anymore.

The command is sent with a SHUTW which force the server to close the
connection after sending its response. However the proxy allows a
keepalive connection on the client side and does not close.

The response analyser does not do much stuff, it only reinits the
connection when it received a close from the server, and forward the
response. It does not analyze the response data.
The only guarantee of the end of the response is the close of the
server, we can't rely on the double \n since it's not send by every
command.

This could be reimplemented later as a filter.
2018-10-28 14:03:06 +01:00
William Lallemand
b9f9e3bc17 MEDIUM: cli: 'show proc' displays processus
This patch implements a command which displays the current processes.

It only works in the CLI of the master.
2018-10-28 13:51:39 +01:00
William Lallemand
291810d8f8 MEDIUM: mworker: find the server ptr using a CLI prefix
Add a struct server pointer in the mworker_proc struct so we can easily
use it as a target for the mworker proxy.

pcli_prefix_to_pid() is used to find the right PID of the worker
when using a prefix in the CLI. (@master, @#<relative pid> , @<pid>)

pcli_pid_to_server() is used to find the right target server for the
CLI proxy.
2018-10-28 13:51:39 +01:00
William Lallemand
14721be11f MEDIUM: cli: disable some keywords in the master
The master process does not need all the keywords of the cli, add 2
flags to chose which keyword to use.

It might be useful to activate some of them in a debug mode later...
2018-10-28 13:51:39 +01:00
William Lallemand
e736115d3a MEDIUM: mworker: create CLI listeners from argv[]
This patch introduces mworker_cli_proxy_new_listener() which allows the
creation of new listeners for the CLI proxy.

Using this function it is possible to create new listeners from the
program arguments with -Sa <unix_socket>. It is allowed to create
multiple listeners with several -Sa.
2018-10-28 13:51:39 +01:00
William Lallemand
8a02257d88 MEDIUM: mworker: proxy for the master CLI
This patch implements a listen proxy within the master. It uses the
sockpair of all the workers as servers.

In the current state of the code, the proxy is only doing round robin on
the CLI of the workers. A CLI mode will be needed to know to which CLI
send the requests.
2018-10-28 13:51:39 +01:00
William Lallemand
6e0db2fa99 MEDIUM: mworker: add proc_list in global.h
Add the process list in types/global.h so it could be accessed from
anywhere.
2018-10-28 13:51:39 +01:00
William Lallemand
1b66361f8d MEDIUM: mworker: move proc_list gen before proxies startup
We need to generate the process list before starting the proxies,
because it will be used to create a proxy in the master
2018-10-28 13:51:38 +01:00
William Lallemand
313bfd18c1 MINOR: server: export new_server() function
The new_server() function will be useful to create a proxy for the
master-worker.
2018-10-28 13:51:38 +01:00
William Lallemand
7e1299bb3a REORG: mworker: move struct mworker_proc to global.h
Move the definition of the mworker_proc structure in types/global.h.
2018-10-28 13:51:38 +01:00
William Lallemand
ce83b4a5dd MEDIUM: mworker: each worker socketpair is a CLI listener
The init code of the mworker_proc structs has been moved before the
init of the listeners.

Each socketpair is now connected to a CLI within the workers, which
allows the master to access their CLI.

The inherited flag of the worker side socketpair is removed so the
socket can be closed in the master.
2018-10-28 13:51:38 +01:00
William Lallemand
f1a62860c8 MINOR: mworker: number of reload in the life of a worker
This patch adds a field in the mworker_proc structure which contains how
much time the master reloaded during the life of a worker.
2018-10-28 13:51:38 +01:00
Willy Tarreau
908d26fd03 MINOR: stream-int: don't needlessly call si_cs_send() in si_cs_process()
There's a call there to si_cs_send() while we're supposed to come from
si_cs_io_cb() which has just done it. But in fact we can also come here
as a lower layer callback from ->wake() after a connection is established.
Since most of the time we'll end up here with either no data in the buffer
or a blocked output, let's simply check if we're already susbcribed to send
events before calling si_cs_send().
2018-10-28 13:50:02 +01:00
Willy Tarreau
0dfccb20f5 MINOR: stream-int: make stream_int_notify() not wake the tasklet up
stream_int_notify() is I/O agnostic and should not wake up the tasklet,
it's up to si_cs_process() to do that, just like si_applet_wake_cb()
does it for the applet.
2018-10-28 13:50:01 +01:00
Willy Tarreau
33a09a5f2a MINOR: stream-int: don't needlessly call tasklet_wakeup() in stream_int_chk_snd_conn()
This one was added by commit 53216e7db ("MEDIUM: connections: Don't
directly mess with the polling from the upper layers.") after the
removal of the conditional cs_want_send() call. But after analysis
it turned out that it's not needed since the si_cs_send() call will
either succeed or subscribe.
2018-10-28 13:50:01 +01:00
Willy Tarreau
eafd8ebcfe MEDIUM: stream-int: call si_cs_process() in stream_int_update_conn
Calling si_cs_send() alone is always dangerous because it can result
in the loss of an event if it manages to empty the buffer. Indeed, in
this case it's critical to call si_chk_rcv() on the opposite stream-int.
Given that si_cs_process() takes care of all this, let's call it instead.
All this code could possibly be refined soon to avoid redoing the whole
stream_int_notify() and do it only after a send(), but at the moment it's
not important.
2018-10-28 13:48:06 +01:00
Willy Tarreau
85f890174a MEDIUM: stream-int: make si_update() synchronize flag changes before the I/O
With the new synchronous si_cs_send() at the end of process_stream(),
we're seeing re-appear the I/O layer specific part of the stream interface
which is supposed to deal with I/O event subscription. The only difference
is that now we subscribe to I/Os only after having attempted (and failed)
them.

This patch brings a cleanup in this by reintroducing stream_int_update_conn()
with the send code from process_stream(). However this alone would not be
enough because the flags which are cleared afterwards would result in the
loss of the possible events (write events only at the moment). So the flags
clearing and stream-int state updates are also performed inside si_update()
between the generic code and the I/O specific code. This definitely makes
sense as after this call we can simply check again for channel and SI flag
changes and decide to loop once again or not.
2018-10-28 13:47:00 +01:00
Willy Tarreau
0f8d3ab362 MEDIUM: stream: don't try to send first in process_stream()
The rationale here is that we should never need to try to send() at the
beginning of process_stream() because :
  - if something was pending, it's very unlikely that it was unblocked
    and not sent just between the last poll() and the wakeup instant.
  - if something pending was recently sent, then we don't have anything
    to send anymore.

So at first glance it doesn't seem like there could be any valid case
where trying to send before entering the function brings any benefit.
2018-10-28 13:47:00 +01:00
Willy Tarreau
18e066c2e7 MEDIUM: stream: always call si_cs_recv() after a failed buffer allocation
If a buffer allocation failed, we have SI_FL_WAIT_ROOM set and c_size(buf)
being zero. It's the only moment where we have a new opportunity to try to
allocate this buffer. However we don't want to waste our time trying this
if both are non-null since it indicates missing room without any changed
condition.
2018-10-28 13:47:00 +01:00
Willy Tarreau
581abd3f99 MEDIUM: stream-int: replace channel_alloc_buffer() with si_alloc_ibuf() everywhere
Well that's only 3 places (applet.c, stream_interface.c, hlua.c). This
ensures we always clear SI_FL_WAIT_ROOM before setting it on failure,
so that it is granted that SI_FL_WAIT_ROOM always indicates a lack of
room for doing an operation, including the inability to allocate a
buffer for this.
2018-10-28 13:47:00 +01:00
Willy Tarreau
0979916d3b MINOR: stream-int: add si_alloc_ibuf() to ease input buffer allocation
This will supersed channel_alloc_buffer() while relying on it. It will
automatically adjust SI_FL_WAIT_ROOM on the stream-int depending on
success or failure to allocate this buffer.

It's worth noting that it could make sense to also set SI_FL_WANT_PUT
each time we do this to further simplify the code at user places such
as applets, but it would possibly not be easy to clean this flag
everywhere an rx operation stops.
2018-10-28 13:47:00 +01:00