MINOR: listener: automatically adjust shards based on support for SO_REUSEPORT
Now if multiple shards are explicitly requested, and the listener's
protocol doesn't support SO_REUSEPORT, sharding is disabled, which will
result in the socket being automatically duped if needed. A warning is
emitted when this happens. If "shards by-group" or "shards by-thread"
are used, these will automatically be turned down to 1 since we want
this to be possible easily using -dR on the command line without having
to djust the config. For "by-thread", a diag warning will be emitted to
help troubleshoot possible performance issues.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 396fc5f..d337c88 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -15297,6 +15297,14 @@
sockets. The load distribution will be a bit less optimal but the contention
(especially in the system) will still be lower than with a single socket.
+ On operating systems that do not support multiple sockets bound to the same
+ address, "by-thread" and "by-group" will automatically fall back to a single
+ shard. For "by-group" this is done without any warning since it doesn't
+ change anything for a single group, and will result in sockets being
+ duplicated for each group anyway. However, for "by-thread", a diagnostic
+ warning will be emitted if this happens since the resulting number of
+ listeners will not be the expected one.
+
ssl
This setting is only available when support for OpenSSL was built in. It
enables SSL deciphering on connections instantiated from this listener. A
diff --git a/src/listener.c b/src/listener.c
index 8a3aa7c..45595cc 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -1668,15 +1668,31 @@
todo = thread_set_count(&bind_conf->thread_set);
/* special values: -1 = "by-thread", -2 = "by-group" */
- if (shards == -1)
- shards = todo;
+ if (shards == -1) {
+ if (li->rx.proto->flags & PROTO_F_REUSEPORT_SUPPORTED)
+ shards = todo;
+ else {
+ if (fe != global.cli_fe)
+ ha_diag_warning("[%s:%d]: Disabling per-thread sharding for listener in"
+ " %s '%s' because SO_REUSEPORT is disabled\n",
+ bind_conf->file, bind_conf->line, proxy_type_str(fe), fe->id);
+ shards = 1;
+ }
+ }
else if (shards == -2)
- shards = my_popcountl(bind_conf->thread_set.grps);
+ shards = (li->rx.proto->flags & PROTO_F_REUSEPORT_SUPPORTED) ? my_popcountl(bind_conf->thread_set.grps) : 1;
/* no more shards than total threads */
if (shards > todo)
shards = todo;
+ /* We also need to check if an explicit shards count was set and cannot be honored */
+ if (shards > 1 && !(li->rx.proto->flags & PROTO_F_REUSEPORT_SUPPORTED)) {
+ ha_warning("[%s:%d]: Disabling sharding for listener in %s '%s' because SO_REUSEPORT is disabled\n",
+ bind_conf->file, bind_conf->line, proxy_type_str(fe), fe->id);
+ shards = 1;
+ }
+
shard = done = grp = bit = mask = 0;
new_li = li;