diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c index fe7e4f4e1ce..3b168d76a3c 100644 --- a/bin/varnishd/cache/cache_backend.c +++ b/bin/varnishd/cache/cache_backend.c @@ -139,16 +139,8 @@ VBE_Connect_Error(struct VSC_vbe *vsc, int err) /*--------------------------------------------------------------------*/ -int -VBE_is_ah_auto(const struct backend *bp) -{ - - CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC); - return (bp->director->vdir->admin_health == VDI_AH_AUTO); -} - -void -VBE_connwait_signal_all(const struct backend *bp) +static void +vbe_connwait_signal_all(const struct backend *bp) { struct connwait *cw; @@ -661,6 +653,21 @@ vbe_healthy(VRT_CTX, VCL_BACKEND d, VCL_TIME *t) return (!bp->sick); } +static VCL_VOID v_matchproto_(vdi_notify_f) +vbe_notify(VCL_BACKEND d) +{ + const struct vdi_ahealth *ah; + struct backend *bp; + + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + CAST_OBJ_NOTNULL(bp, d->priv, BACKEND_MAGIC); + CHECK_OBJ_NOTNULL(d->vdir, VCLDIR_MAGIC); + ah = d->vdir->admin_health; + + // sick == 0 for _noprobe + if (ah == VDI_AH_SICK || (ah == VDI_AH_AUTO && bp->sick)) + vbe_connwait_signal_all(bp); +} /*-------------------------------------------------------------------- */ @@ -676,7 +683,8 @@ static const struct vdi_methods vbe_methods[1] = {{ .destroy = vbe_destroy, .panic = vbe_panic, .list = vbe_list, - .healthy = vbe_healthy + .healthy = vbe_healthy, + .notify = vbe_notify }}; static const struct vdi_methods vbe_methods_noprobe[1] = {{ @@ -689,7 +697,8 @@ static const struct vdi_methods vbe_methods_noprobe[1] = {{ .event = vbe_dir_event, .destroy = vbe_destroy, .panic = vbe_panic, - .list = vbe_list + .list = vbe_list, + .notify = vbe_notify }}; /*-------------------------------------------------------------------- diff --git a/bin/varnishd/cache/cache_backend_probe.c b/bin/varnishd/cache/cache_backend_probe.c index 3b4fa2fa821..3941785f7de 100644 --- a/bin/varnishd/cache/cache_backend_probe.c +++ b/bin/varnishd/cache/cache_backend_probe.c @@ -191,10 +191,8 @@ VBP_Update_Backend(struct vbp_target *vt) i = (vt->good < vt->threshold); chg = (i != vt->backend->sick); vt->backend->sick = i; - if (i && chg && (vt->backend->director != NULL && - VBE_is_ah_auto(vt->backend))) { - VBE_connwait_signal_all(vt->backend); - } + if (i && chg && vt->backend->director != NULL) + VRT_Notify(vt->backend->director); AN(vt->backend->vcl_name); VSL(SLT_Backend_health, NO_VXID, diff --git a/bin/varnishd/cache/cache_director.c b/bin/varnishd/cache/cache_director.c index 042ad9f345e..f15b5acd450 100644 --- a/bin/varnishd/cache/cache_director.c +++ b/bin/varnishd/cache/cache_director.c @@ -265,6 +265,22 @@ VRT_SetChanged(VCL_BACKEND d, VCL_TIME changed) d->vdir->health_changed = changed; } +/*-------------------------------------------------------------------- + * Notify of change (admin_health for now) outside backend + */ + +VCL_VOID +VRT_Notify(VCL_BACKEND d) +{ + + CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); + CHECK_OBJ_NOTNULL(d->vdir, VCLDIR_MAGIC); + CHECK_OBJ_NOTNULL(d->vdir->methods, VDI_METHODS_MAGIC); + if (d->vdir->methods->notify == NULL) + return; + d->vdir->methods->notify(d); +} + /* Send Event ---------------------------------------------------------- */ @@ -477,7 +493,6 @@ static int v_matchproto_(vcl_be_func) do_set_health(struct cli *cli, struct director *d, void *priv) { struct set_health *sh; - struct vrt_ctx *ctx; (void)cli; CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); @@ -488,12 +503,7 @@ do_set_health(struct cli *cli, struct director *d, void *priv) if (d->vdir->admin_health != sh->ah) { d->vdir->health_changed = VTIM_real(); d->vdir->admin_health = sh->ah; - ctx = VCL_Get_CliCtx(0); - if (sh->ah == VDI_AH_SICK || (sh->ah == VDI_AH_AUTO && - d->vdir->methods->healthy != NULL && - !d->vdir->methods->healthy(ctx, d, NULL))) { - VBE_connwait_signal_all(d->priv); - } + VRT_Notify(d); } return (0); } diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h index e0b88b4aae9..e84f90e0f0e 100644 --- a/bin/varnishd/cache/cache_varnishd.h +++ b/bin/varnishd/cache/cache_varnishd.h @@ -161,11 +161,7 @@ void VCA_Init(void); void VCA_Shutdown(void); /* cache_backend.c */ -struct backend; - void VBE_InitCfg(void); -void VBE_connwait_signal_all(const struct backend *bp); -int VBE_is_ah_auto(const struct backend *bp); /* cache_ban.c */ diff --git a/include/vrt.h b/include/vrt.h index 144a7e2ed16..95928c2f38c 100644 --- a/include/vrt.h +++ b/include/vrt.h @@ -46,7 +46,7 @@ # error "include vdef.h before vrt.h" #endif -#define VRT_MAJOR_VERSION 20U +#define VRT_MAJOR_VERSION 21U #define VRT_MINOR_VERSION 0U @@ -58,6 +58,9 @@ * binary/load-time compatible, increment MAJOR version * * NEXT (2024-03-15) + * 21.0 + * notify callback added to struct vdi_methods + * VRT_Notify() added * 20.0 (2024-09-13) * struct vrt_backend.backend_wait_timeout added * struct vrt_backend.backend_wait_limit added @@ -737,6 +740,7 @@ typedef void vdi_release_f(VCL_BACKEND); typedef void vdi_destroy_f(VCL_BACKEND); typedef void vdi_panic_f(VCL_BACKEND, struct vsb *); typedef void vdi_list_f(VRT_CTX, VCL_BACKEND, struct vsb *, int, int); +typedef void vdi_notify_f(VCL_BACKEND); struct vdi_methods { unsigned magic; @@ -755,6 +759,9 @@ struct vdi_methods { vdi_destroy_f *destroy; vdi_panic_f *panic; vdi_list_f *list; + // when something changes outside the backend's control + // (for now, admin health) + vdi_notify_f *notify; }; struct director { @@ -767,6 +774,7 @@ struct director { }; VCL_BOOL VRT_Healthy(VRT_CTX, VCL_BACKEND, VCL_TIME *); +VCL_VOID VRT_Notify(VCL_BACKEND); VCL_VOID VRT_SetChanged(VCL_BACKEND, VCL_TIME); VCL_BACKEND VRT_AddDirector(VRT_CTX, const struct vdi_methods *, void *, const char *, ...) v_printflike_(4, 5);