MINOR: listeners: add clone_listener() to duplicate listeners at boot time

This function's purpose will be to duplicate a listener in INIT state.
This will be used to ease declaration of listeners spanning multiple
groups, which will thus require multiple FDs hence multiple receivers.
This commit is contained in:
Willy Tarreau 2021-10-12 09:36:10 +02:00
parent 01cac3f721
commit 59a877dfd9
2 changed files with 50 additions and 0 deletions

View File

@ -98,6 +98,7 @@ void unbind_listener(struct listener *listener);
*/
int create_listeners(struct bind_conf *bc, const struct sockaddr_storage *ss,
int portl, int porth, int fd, struct protocol *proto, char **err);
struct listener *clone_listener(struct listener *src);
/* Delete a listener from its protocol's list of listeners. The listener's
* state is automatically updated from LI_ASSIGNED to LI_INIT. The protocol's

View File

@ -663,6 +663,55 @@ int create_listeners(struct bind_conf *bc, const struct sockaddr_storage *ss,
return 1;
}
/* clones listener <src> and returns the new one. All dynamically allocated
* fields are reallocated (name for now). The new listener is inserted before
* the original one in the bind_conf and frontend lists. This allows it to be
* duplicated while iterating over the current list. The original listener must
* only be in the INIT or ASSIGNED states, and the new listener will only be
* placed into the INIT state. The counters are always set to NULL. Maxsock is
* updated. Returns NULL on allocation error.
*/
struct listener *clone_listener(struct listener *src)
{
struct listener *l;
l = calloc(1, sizeof(*l));
if (!l)
goto oom1;
memcpy(l, src, sizeof(*l));
if (l->name) {
l->name = strdup(l->name);
if (!l->name)
goto oom2;
}
l->rx.owner = l;
l->state = LI_INIT;
l->counters = NULL;
l->extra_counters = NULL;
LIST_APPEND(&src->by_fe, &l->by_fe);
LIST_APPEND(&src->by_bind, &l->by_bind);
MT_LIST_INIT(&l->wait_queue);
l->rx.proto->add(l->rx.proto, l);
HA_SPIN_INIT(&l->lock);
_HA_ATOMIC_INC(&jobs);
_HA_ATOMIC_INC(&listeners);
global.maxsock++;
return l;
oom3:
free(l->name);
oom2:
free(l);
oom1:
return l;
}
/* Delete a listener from its protocol's list of listeners. The listener's
* state is automatically updated from LI_ASSIGNED to LI_INIT. The protocol's
* number of listeners is updated, as well as the global number of listeners