Changeset 704df2


Ignore:
Timestamp:
2010-02-01 09:29:16 (4 years ago)
Author:
Poul-Henning Kamp <phk@…>
Branches:
master, 3.0, 4.0, experimental-ims
Children:
95378f
Parents:
c1f856
git-author:
Poul-Henning Kamp <phk@…> (2010-02-01 09:29:16)
git-committer:
Poul-Henning Kamp <phk@…> (2010-02-01 09:29:16)
Message:

Make the trouble-list hold a uintptr_t of the objhead, instead of the
actual objhead, to make it painfully obvious, that no dereference is
allowed.

Various strokes with the polishing cloth along the way.

git-svn-id:  http://www.varnish-cache.org/svn/trunk/varnish-cache@4514 d4fa192b-c00b-0410-8231-f00ffab90ce4

Location:
bin/varnishd
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • bin/varnishd/cache.h

    rc1f856 r704df2  
    457457 
    458458struct vbe_conn *VBE_GetFd(const struct director *, struct sess *sp); 
    459 int VBE_Healthy(const struct director *, const struct sess *sp); 
     459int VBE_Healthy(double now, const struct director *, uintptr_t target); 
     460int VBE_Healthy_sp(const struct sess *sp, const struct director *); 
    460461void VBE_ClosedFd(struct sess *sp); 
    461462void VBE_RecycleFd(struct sess *sp); 
  • bin/varnishd/cache_backend.c

    r5bc21e r704df2  
    244244 
    245245static unsigned int 
    246 vbe_Healthy(const struct sess *sp, struct backend *backend) 
     246vbe_Healthy(double now, uintptr_t target, struct backend *backend) 
    247247{ 
    248248        struct trouble *tr; 
    249249        struct trouble *tr2; 
    250         struct trouble *old = NULL; 
    251         unsigned i = 0; 
     250        struct trouble *old; 
     251        unsigned i = 0, retval; 
    252252        unsigned int threshold; 
    253         CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); 
     253 
    254254        CHECK_OBJ_NOTNULL(backend, BACKEND_MAGIC); 
    255255 
    256256        if (!backend->healthy) 
    257                 return 0; 
     257                return (0); 
    258258 
    259259        /* VRT/VCC sets threshold to UINT_MAX to mark that it's not 
     
    267267        /* Saintmode is disabled */ 
    268268        if (threshold == 0) 
    269                 return 1; 
     269                return (1); 
    270270 
    271271        /* No need to test if we don't have an object head to test against. 
    272272         * FIXME: Should check the magic too, but probably not assert? 
    273273         */ 
    274         if (!sp->objhead) 
    275                 return 1; 
    276  
     274        if (target == 0) 
     275                return (1); 
     276 
     277        old = NULL; 
     278        retval = 1; 
    277279        Lck_Lock(&backend->mtx); 
    278280        VTAILQ_FOREACH_SAFE(tr, &backend->troublelist, list, tr2) { 
    279281                CHECK_OBJ_NOTNULL(tr, TROUBLE_MAGIC); 
    280                 if (tr->timeout < sp->t_req) { 
     282 
     283                if (tr->timeout < now) { 
    281284                        VTAILQ_REMOVE(&backend->troublelist, tr, list); 
    282285                        old = tr; 
     286                        retval = 1; 
    283287                        break; 
    284288                } 
    285289 
    286                 if (tr->objhead == sp->objhead) { 
    287                         Lck_Unlock(&backend->mtx); 
    288                         return 0; 
     290                if (tr->target == target) { 
     291                        retval = 0; 
     292                        break; 
    289293                } 
    290294 
     
    293297                 * instead of i++ to allow this behavior. 
    294298                 */ 
    295                 if (++i >=threshold) { 
    296                         Lck_Unlock(&backend->mtx); 
    297                         return 0; 
     299                if (++i >= threshold) { 
     300                        retval = 0; 
     301                        break; 
    298302                } 
    299303        } 
    300304        Lck_Unlock(&backend->mtx); 
    301305 
    302         if (old) 
     306        if (old != NULL) 
    303307                FREE_OBJ(old); 
    304308 
    305         return 1; 
     309        return (retval); 
    306310} 
    307311 
     
    343347        } 
    344348 
    345         if (!vbe_Healthy(sp, bp)) { 
     349        if (!vbe_Healthy(sp->t_req, (uintptr_t)sp->objhead, bp)) { 
    346350                VSL_stats->backend_unhealthy++; 
    347351                return (NULL); 
     
    424428} 
    425429 
    426 /* Check health ------------------------------------------------------*/ 
     430/* Check health ------------------------------------------------------ 
     431 * 
     432 * The target is really an objhead pointer, but since it can not be 
     433 * dereferenced during health-checks, we pass it as uintptr_t, which 
     434 * hopefully will make people investigate, before mucking about with it. 
     435 */ 
    427436 
    428437int 
    429 VBE_Healthy(const struct director *d, const struct sess *sp) 
     438VBE_Healthy_sp(const struct sess *sp, const struct director *d) 
    430439{ 
    431440 
    432441        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); 
    433         if (d == NULL) 
    434                 d = sp->director; 
    435442        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); 
    436         return (d->healthy(d, sp)); 
     443        return (d->healthy(sp->t_req, d, (uintptr_t)sp->objhead)); 
     444} 
     445 
     446int 
     447VBE_Healthy(double now, const struct director *d, uintptr_t target) 
     448{ 
     449 
     450        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); 
     451        return (d->healthy(now, d, target)); 
    437452} 
    438453 
     
    470485 
    471486static unsigned 
    472 vdi_simple_healthy(const struct director *d, const struct sess *sp) 
     487vdi_simple_healthy(double now, const struct director *d, uintptr_t target) 
    473488{ 
    474489        struct vdi_simple *vs; 
    475490 
    476         CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); 
    477491        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); 
    478492        CAST_OBJ_NOTNULL(vs, d->priv, VDI_SIMPLE_MAGIC); 
    479         return (vbe_Healthy(sp, vs->backend)); 
     493        return (vbe_Healthy(now, target, vs->backend)); 
    480494} 
    481495 
  • bin/varnishd/cache_backend.h

    r6032765 r704df2  
    8080typedef struct vbe_conn *vdi_getfd_f(const struct director *, struct sess *sp); 
    8181typedef void vdi_fini_f(struct director *); 
    82 typedef unsigned vdi_healthy(const struct director *, const struct sess *sp); 
     82typedef unsigned vdi_healthy(double now, const struct director *, 
     83    uintptr_t target); 
    8384 
    8485struct director { 
     
    100101        unsigned                magic; 
    101102#define TROUBLE_MAGIC           0x4211ab21 
    102         void                    *objhead; /* NB: only comparison */ 
     103        uintptr_t               target; 
    103104        double                  timeout; 
    104105        VTAILQ_ENTRY(trouble)   list; 
  • bin/varnishd/cache_dir_random.c

    rf6f30f r704df2  
    138138                                continue; 
    139139                        d2 = vs->hosts[i].backend; 
    140                         if (!VBE_Healthy(d2, sp)) 
     140                        if (!VBE_Healthy_sp(sp, d2)) 
    141141                                break; 
    142142                        vbe = VBE_GetFd(d2, sp); 
     
    153153                        d2 = vs->hosts[i].backend; 
    154154                        /* XXX: cache result of healty to avoid double work */ 
    155                         if (VBE_Healthy(d2, sp)) 
     155                        if (VBE_Healthy_sp(sp, d2)) 
    156156                                s1 += vs->hosts[i].weight; 
    157157                } 
     
    172172                for (i = 0; i < vs->nhosts; i++)  { 
    173173                        d2 = vs->hosts[i].backend; 
    174                         if (!VBE_Healthy(d2, sp)) 
     174                        if (!VBE_Healthy_sp(sp, d2)) 
    175175                                continue; 
    176176                        s1 += vs->hosts[i].weight; 
     
    188188 
    189189static unsigned 
    190 vdi_random_healthy(const struct director *d, const struct sess *sp) 
     190vdi_random_healthy(double now, const struct director *d, uintptr_t target) 
    191191{ 
    192192        struct vdi_random *vs; 
    193193        int i; 
    194194 
    195         CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); 
    196195        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); 
    197196        CAST_OBJ_NOTNULL(vs, d->priv, VDI_RANDOM_MAGIC); 
    198197 
    199198        for (i = 0; i < vs->nhosts; i++) { 
    200                 if (VBE_Healthy(vs->hosts[i].backend, sp)) 
     199                if (VBE_Healthy(now, vs->hosts[i].backend, target)) 
    201200                        return 1; 
    202201        } 
  • bin/varnishd/cache_dir_round_robin.c

    r9aed2f r704df2  
    7676                backend = vs->hosts[vs->next_host].backend; 
    7777                vs->next_host = (vs->next_host + 1) % vs->nhosts; 
    78                 if (!VBE_Healthy(backend, sp)) 
     78                if (!VBE_Healthy_sp(sp, backend)) 
    7979                        continue; 
    8080                vbe = VBE_GetFd(backend, sp); 
     
    8787 
    8888static unsigned 
    89 vdi_round_robin_healthy(const struct director *d, const struct sess *sp) 
     89vdi_round_robin_healthy(double now, const struct director *d, uintptr_t target) 
    9090{ 
    9191        struct vdi_round_robin *vs; 
     
    9393        int i; 
    9494 
    95         CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); 
    9695        CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC); 
    9796        CAST_OBJ_NOTNULL(vs, d->priv, VDI_ROUND_ROBIN_MAGIC); 
     
    9998        for (i = 0; i < vs->nhosts; i++) { 
    10099                backend = vs->hosts[i].backend; 
    101                 if (VBE_Healthy(backend, sp)) 
     100                if (VBE_Healthy(now, backend, target)) 
    102101                        return 1; 
    103102        } 
  • bin/varnishd/cache_hash.c

    rc1f856 r704df2  
    188188} 
    189189 
    190 /********************************************************************** 
     190/*--------------------------------------------------------------------- 
    191191 * This is a debugging hack to enable testing of boundary conditions 
    192192 * in the hash algorithm. 
     
    395395         * set here? FIXME:Grace. 
    396396         */ 
    397         sp->objhead = oh; 
    398         if (oc == NULL && grace_oc != NULL && 
    399             (busy_oc != NULL || !VBE_Healthy(NULL, sp))) { 
     397        if (oc == NULL                  /* We found no live object */ 
     398            && grace_oc != NULL         /* There is a grace candidate */ 
     399            && (busy_oc != NULL         /* Somebody else is already busy */ 
     400            || !VBE_Healthy(sp->t_req, sp->director, (uintptr_t)oh))) { 
     401                                         /* Or it is impossible to fetch: */ 
    400402                o = grace_oc->obj; 
    401403                CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); 
     
    403405                        oc = grace_oc; 
    404406        } 
    405         sp->objhead = NULL; 
    406407 
    407408        if (oc != NULL) { 
  • bin/varnishd/cache_vrt.c

    r8c8c7e r704df2  
    309309        ALLOC_OBJ(new, TROUBLE_MAGIC); 
    310310        AN(new); 
    311         new->objhead = sp->objhead; 
     311        new->target = (uintptr_t)sp->objhead; 
    312312        new->timeout = sp->t_req + a; 
    313313 
     
    783783        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); 
    784784        CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC); 
    785         return (VBE_Healthy(NULL, sp)); 
     785        return (VBE_Healthy_sp(sp, sp->director)); 
    786786} 
    787787 
Note: See TracChangeset for help on using the changeset viewer.