]> git.kaiwu.me - haproxy.git/commitdiff
MEDIUM: proxy: implement backend deletion
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 6 Jan 2026 14:26:13 +0000 (15:26 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 2 Mar 2026 13:14:05 +0000 (14:14 +0100)
This patch finalizes "del backend" handler by implementing the proper
proxy deletion.

After ensuring backend deletion can be performed, several steps are
executed. First, any watcher elements are updated to point on the next
proxy instance. The backend is then removed from ID and name global
trees and is finally detached from proxies_list.

Once the backend instance is removed from proxies_list, the backend
cannot be found by new elements. Thread isolation is lifted and
proxy_drop() is called, which will purge the proxy if its refcount is
null. Thanks to recently introduced PROXIES_DEL_LOCK, proxy_drop() is
thread safe.

src/proxy.c

index f52cc08f860db617f3f6d8c91a92fc870608f481..ab054382745bea98f77a4d3d9db1e3ccb9351d4f 100644 (file)
@@ -5098,7 +5098,8 @@ int be_check_for_deletion(const char *bename, struct proxy **pb, const char **pm
 /* Handler for "delete backend". Runs under thread isolation. Always returns 1. */
 static int cli_parse_delete_backend(char **args, char *payload, struct appctx *appctx, void *private)
 {
-       struct proxy *px;
+       struct watcher *px_watch;
+       struct proxy *px, *prev;
        const char *msg;
        char *be_name;
        int ret;
@@ -5120,11 +5121,32 @@ static int cli_parse_delete_backend(char **args, char *payload, struct appctx *a
                goto out;
        }
 
+       while (!MT_LIST_ISEMPTY(&px->watcher_list)) {
+               px_watch = MT_LIST_NEXT(&px->watcher_list, struct watcher *, el);
+               watcher_next(px_watch, px->next);
+       }
+
+       ceb32_item_delete(&used_proxy_id, conf.uuid_node, uuid, px);
+       cebis_item_delete(&proxy_by_name, conf.name_node, id, px);
+
+       /* Detach backend from global proxies_list. */
+       if (proxies_list == px) {
+               proxies_list = px->next;
+       }
+       else {
+               for (prev = proxies_list->next; prev && prev->next != px; prev = prev->next)
+                       ;
+               BUG_ON(!prev); /* Proxy instance not found in global list ? */
+               prev->next = px->next;
+       }
+
        px->flags |= PR_FL_DELETED;
 
        thread_release();
 
        ha_notice("Backend deleted.\n");
+       proxy_drop(px);
+
        cli_umsg(appctx, LOG_INFO);
        return 1;