MINOR: server: better mt_list usage for node migration (prev_deleted handling)

Now that mt_list v2 api was merged into haproxy's codebase in 4e65fc6 ("
MAJOR: import: update mt_list to support exponential back-off (try #2)"),
let's fix a hack in cli_parse_delete_server() which abused from mt_list
api to migrate an element from one list to another: there used to be a
tiny race there between the pop and the append operations, race that was
compensated by the fact that it was performed under full thread isolation.

However that was a bad example of the mt_list API which could have
resulted in actual bug if the code was duplicated elsewhere without thread
isolation. To fix this, we now make use of the
MT_LIST_FOR_EACH_ENTRY_LOCKED() macro which allows us to simply migrate
the current element to another list since the element is appended into
another one while still in busy state and then unlinked from the original
list.
This commit is contained in:
Aurelien DARRAGON 2024-07-15 15:44:49 +02:00
parent 75b335abc7
commit 05f33e95ba

View File

@ -6108,18 +6108,19 @@ static int cli_parse_delete_server(char **args, char *payload, struct appctx *ap
_srv_detach(srv); _srv_detach(srv);
/* Some deleted servers could still point to us using their 'next', /* Some deleted servers could still point to us using their 'next',
* update them as needed * migrate them as needed
* Please note the small race between the POP and APPEND, although in
* this situation this is not an issue as we are under full thread
* isolation
*/ */
while ((prev_del = MT_LIST_POP(&srv->prev_deleted, struct server *, prev_deleted))) { MT_LIST_FOR_EACH_ENTRY_LOCKED(prev_del, &srv->prev_deleted, prev_deleted, back) {
/* update its 'next' ptr */ /* update its 'next' ptr */
prev_del->next = srv->next; prev_del->next = srv->next;
if (srv->next) { if (srv->next) {
/* now it is our 'next' responsibility */ /* now it is our 'next' responsibility */
MT_LIST_APPEND(&srv->next->prev_deleted, &prev_del->prev_deleted); MT_LIST_APPEND(&srv->next->prev_deleted, &prev_del->prev_deleted);
} }
else
mt_list_unlock_self(&prev_del->prev_deleted);
/* unlink from our list */
prev_del = NULL;
} }
/* we ourselves need to inform our 'next' that we will still point it */ /* we ourselves need to inform our 'next' that we will still point it */