]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: listener: add relax_listener() function
authorAurelien DARRAGON <adarragon@haproxy.com>
Wed, 15 Feb 2023 08:30:54 +0000 (09:30 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 23 Feb 2023 14:05:05 +0000 (15:05 +0100)
There is a need for a small difference between resuming and relaxing
a listener.

When resuming, we expect that the listener may completely resume, this includes
unpausing or rebinding if required.
Resuming a listener is a best-effort operation: no matter the current state,
try our best to bring the listener up to the LI_READY state.

There are some cases where we only want to "relax" listeners that were
previously restricted using limit_listener() or listener_full() functions.
Here we don't want to ressucitate listeners, we're simply interested in
cancelling out the previous restriction.

To this day, listener_resume() on a unbound listener is broken, that's why
the need for this wasn't felt yet.

But we're trying to restore historical listener_resume() behavior, so we better
prepare for this by introducing an explicit relax_listener() function that
only does what is expected in such cases.

This commit depends on:
 - "MINOR: listener/api: add lli hint to listener functions"

include/haproxy/listener.h
src/listener.c

index 2b6c3dc27dd72d118de4d8de0ab5013e303709ec..0017372392adf2b281dcd3e3d8674ef91030ff67 100644 (file)
@@ -59,6 +59,18 @@ int pause_listener(struct listener *l, int lpx, int lli);
  */
 int resume_listener(struct listener *l, int lpx, int lli);
 
+/* Same as resume_listener(), but will only work to resume from
+ * LI_FULL or LI_LIMITED states because we try to relax listeners that
+ * were temporarily restricted and not to resume inactive listeners that
+ * may have been paused or completely stopped in the meantime.
+ * Returns positive value for success and 0 for failure.
+ * It will need to operate under the proxy's lock and the listener's lock.
+ * The caller is responsible for indicating in lpx, lli whether the respective
+ * locks are already held (non-zero) or not (zero) so that the function pick
+ * the missing ones, in this order.
+ */
+int relax_listener(struct listener *l, int lpx, int lli);
+
 /*
  * This function completely stops a listener. It will need to operate under the
  * proxy's lock, the protocol's and the listener's lock. The caller is
index 2956722337cc9f7a52c23a91ebe761cca87f4794..ce7410546312a9a8dd4e2bef2f19e40e7fef5bdf 100644 (file)
@@ -571,6 +571,33 @@ int resume_listener(struct listener *l, int lpx, int lli)
        return ret;
 }
 
+/* Same as resume_listener(), but will only work to resume from
+ * LI_FULL or LI_LIMITED states because we try to relax listeners that
+ * were temporarily restricted and not to resume inactive listeners that
+ * may have been paused or completely stopped in the meantime.
+ * Returns positive value for success and 0 for failure.
+ * It will need to operate under the proxy's lock and the listener's lock.
+ * The caller is responsible for indicating in lpx, lli whether the respective
+ * locks are already held (non-zero) or not (zero) so that the function pick
+ * the missing ones, in this order.
+ */
+int relax_listener(struct listener *l, int lpx, int lli)
+{
+       int ret = 1;
+
+       if (!lli)
+               HA_RWLOCK_WRLOCK(LISTENER_LOCK, &l->lock);
+
+       if (l->state != LI_FULL && l->state != LI_LIMITED)
+               goto end; /* listener may be suspended or even stopped */
+       ret = resume_listener(l, lpx, 1);
+
+ end:
+       if (!lli)
+               HA_RWLOCK_WRUNLOCK(LISTENER_LOCK, &l->lock);
+       return ret;
+}
+
 /* Marks a ready listener as full so that the stream code tries to re-enable
  * it upon next close() using resume_listener().
  */