MINOR: protocol: add a function to check if some features are supported

The new function protocol_supports_flag() checks the protocol flags
to verify if some features are supported, but will support being
extended to refine the tests. Let's use it to check for REUSEPORT.
This commit is contained in:
Willy Tarreau 2023-04-22 17:39:30 +02:00
parent c1fbdd6397
commit 8a5e6f4cca
3 changed files with 30 additions and 3 deletions

View File

@ -44,6 +44,14 @@ void protocol_clrf_all(uint flag);
/* sets flag <flag> on all protocols. */
void protocol_setf_all(uint flag);
/* Checks if protocol <proto> supports PROTO_F flag <flag>. Returns zero if not,
* non-zero if supported. It may return a cached value from a previous test,
* and may run live tests then update the proto's flags to cache a result. It's
* better to call it only if needed so that it doesn't result in modules being
* loaded in case of a live test.
*/
int protocol_supports_flag(struct protocol *proto, uint flag);
/* binds all listeners of all registered protocols. Returns a composition
* of ERR_NONE, ERR_RETRYABLE, ERR_FATAL, ERR_ABORT.
*/

View File

@ -1669,7 +1669,7 @@ int bind_complete_thread_setup(struct bind_conf *bind_conf, int *err_code)
/* special values: -1 = "by-thread", -2 = "by-group" */
if (shards == -1) {
if (li->rx.proto->flags & PROTO_F_REUSEPORT_SUPPORTED)
if (protocol_supports_flag(li->rx.proto, PROTO_F_REUSEPORT_SUPPORTED))
shards = todo;
else {
if (fe != global.cli_fe)
@ -1680,14 +1680,14 @@ int bind_complete_thread_setup(struct bind_conf *bind_conf, int *err_code)
}
}
else if (shards == -2)
shards = (li->rx.proto->flags & PROTO_F_REUSEPORT_SUPPORTED) ? my_popcountl(bind_conf->thread_set.grps) : 1;
shards = protocol_supports_flag(li->rx.proto, 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)) {
if (shards > 1 && !protocol_supports_flag(li->rx.proto, 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;

View File

@ -83,6 +83,25 @@ void protocol_setf_all(uint flag)
HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock);
}
/* Checks if protocol <proto> supports PROTO_F flag <flag>. Returns zero if not,
* non-zero if supported. It may return a cached value from a previous test,
* and may run live tests then update the proto's flags to cache a result. It's
* better to call it only if needed so that it doesn't result in modules being
* loaded in case of a live test. It is only supposed to be used during boot.
*/
int protocol_supports_flag(struct protocol *proto, uint flag)
{
if (flag == PROTO_F_REUSEPORT_SUPPORTED) {
/* check if the protocol supports SO_REUSEPORT */
if (!(_HA_ATOMIC_LOAD(&proto->flags) & PROTO_F_REUSEPORT_SUPPORTED))
return 0;
/* OK it looks like it is supported */
return 1;
}
return 0;
}
/* binds all listeners of all registered protocols. Returns a composition
* of ERR_NONE, ERR_RETRYABLE, ERR_FATAL.
*/