/* 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.
*/
/* 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)
}
}
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;
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.
*/