You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

57 lines
2.6 KiB

  1. commit f87ea7d2fdcfa3ccd5d605b3ce96642d28f20f6b
  2. Author: Willy Tarreau <w@1wt.eu>
  3. Date: Fri Aug 24 14:31:53 2018 +0200
  4. BUG/MEDIUM: unix: provide a ->drain() function
  5. Right now conn_sock_drain() calls the protocol's ->drain() function if
  6. it exists, otherwise it simply tries to disable polling for receiving
  7. on the connection. This doesn't work well anymore since we've implemented
  8. the muxes in 1.8, and it has a side effect with keep-alive backend
  9. connections established over unix sockets. What happens is that if
  10. during the idle time after a request, a connection reports some data,
  11. si_idle_conn_null_cb() is called, which will call conn_sock_drain().
  12. This one sees there's no drain() on unix sockets and will simply disable
  13. polling for data on the connection. But it doesn't do anything on the
  14. conn_stream. Thus while leaving the conn_fd_handler, the mux's polling
  15. is updated and recomputed based on the conn_stream's polling state,
  16. which is still enabled, and nothing changes, so we see the process
  17. use 100% CPU in this case because the FD remains active in the cache.
  18. There are several issues that need to be addressed here. The first and
  19. most important is that we cannot expect some protocols to simply stop
  20. reading data when asked to drain pending data. So this patch make the
  21. unix sockets rely on tcp_drain() since the functions are the same. This
  22. solution is appropriate for backporting, but a better one is desired for
  23. the long term. The second issue is that si_idle_conn_null_cb() shouldn't
  24. drain the connection but the conn_stream.
  25. At the moment we don't have any way to drain a conn_stream, though a flag
  26. on rcv_buf() will do it well. Until we support muxes on the server side
  27. it is not a problem so this part can be addressed later.
  28. This fix must be backported to 1.8.
  29. (cherry picked from commit fe5d2ac65fd58a8320e8dc725219c1bce5839592)
  30. Signed-off-by: Willy Tarreau <w@1wt.eu>
  31. diff --git a/src/proto_uxst.c b/src/proto_uxst.c
  32. index f2374be6..0b3a57b8 100644
  33. --- a/src/proto_uxst.c
  34. +++ b/src/proto_uxst.c
  35. @@ -42,6 +42,7 @@
  36. #include <proto/listener.h>
  37. #include <proto/log.h>
  38. #include <proto/protocol.h>
  39. +#include <proto/proto_tcp.h>
  40. #include <proto/task.h>
  41. static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen);
  42. @@ -71,6 +72,7 @@ static struct protocol proto_unix = {
  43. .disable_all = disable_all_listeners,
  44. .get_src = uxst_get_src,
  45. .get_dst = uxst_get_dst,
  46. + .drain = tcp_drain,
  47. .pause = uxst_pause_listener,
  48. .add = uxst_add_listener,
  49. .listeners = LIST_HEAD_INIT(proto_unix.listeners),