const char *srv_op_st_chg_cause(enum srv_op_st_chg_cause cause);
void srv_event_hdl_publish_check(struct server *srv, struct check *check);
+int srv_in_use(const struct server *srv);
int srv_check_for_deletion(const char *bename, const char *svname, enum pr_del_mode del_mode,
struct proxy **pb, struct server **ps, const char **pm);
void srv_unregister(struct server *srv);
static int proxy_purge_servers(struct proxy *px, int max_srv_delete)
{
struct server *srv;
- int ret;
while (!LIST_ISEMPTY(&px->servers_purge)) {
if (!max_srv_delete)
continue;
}
- /* TODO unnecessary server lookup */
- ret = srv_check_for_deletion(px->id, srv->id, PR_DEL_MODE_SYNC, NULL, NULL, NULL);
- if (ret < 0) {
- srv_cancel_purge(srv);
- LIST_DEL_INIT(&srv->el_alt);
- }
- else if (ret > 0) {
- ha_notice("Server '%s/%s' purged.\n", px->id, srv->id);
- srv_unregister(srv);
- srv_drop(srv);
- --max_srv_delete;
- }
- else {
- /* Interrupt work on first server not yet removable. */
+ /* A non removable server must not be flagged for purge. */
+ BUG_ON(srv->flags & (SRV_F_NON_PURGEABLE | SRV_F_NAME_REFD));
+
+ if (srv_in_use(srv))
break;
- }
+
+ ha_notice("Server '%s/%s' purged.\n", px->id, srv->id);
+ srv_unregister(srv);
+ srv_drop(srv);
+ --max_srv_delete;
}
return !(LIST_ISEMPTY(&px->servers_purge) || max_srv_delete);
return 0;
}
/* Returns 1 if the server has streams pointing to it, and 0 otherwise. */
-static int srv_has_streams(struct server *srv)
+static int srv_has_streams(const struct server *srv)
{
int i;
return 1;
}
+/* Returns true if <srv> can be considered as active, i.e. there is active,
+ * pending and/or idle connections on it. Connections scheduled for purging are
+ * still accounted there.
+ */
+int srv_in_use(const struct server *srv)
+{
+ return !!(_HA_ATOMIC_LOAD(&srv->curr_used_conns) ||
+ _HA_ATOMIC_LOAD(&srv->queueslength) || srv_has_streams(srv) ||
+ _HA_ATOMIC_LOAD(&srv->curr_idle_conns) || _HA_ATOMIC_LOAD(&srv->curr_sess_idle_conns));
+}
+
/* Checks if the server <bename>/<svname> exists and is ready for being
* deleted. This means that the server is in maintenance with no streams
* attached to it, no queue and no used idle conns. This is not supposed to
/* Second, conditions that may change over time */
ret = 0;
- /* Ensure that there is no active/pending/idle connection on the server.
- * Note that idle conns scheduled for purging are still accounted in idle counter.
- */
- if (_HA_ATOMIC_LOAD(&srv->curr_used_conns) ||
- _HA_ATOMIC_LOAD(&srv->queueslength) || srv_has_streams(srv) ||
- _HA_ATOMIC_LOAD(&srv->curr_idle_conns) || _HA_ATOMIC_LOAD(&srv->curr_sess_idle_conns)) {
+ /* Ensure that there is no active/pending/idle connection on the server. */
+ if (srv_in_use(srv)) {
msg = "Server still has connections attached to it, cannot remove it.";
goto leave;
}
strack->trackers = srv;
strack->flags |= SRV_F_NAME_REFD;
+ /* Cancel background deletion on tracked server if activated. */
+ if (srv->flags & SRV_F_DYNAMIC)
+ srv_cancel_purge(strack);
+
ha_free(&srv->trackit);
return 0;