~ubuntu-branches/ubuntu/oneiric/squid3/oneiric-security

« back to all changes in this revision

Viewing changes to src/store_digest.cc

  • Committer: Bazaar Package Importer
  • Author(s): Luigi Gangitano
  • Date: 2007-05-13 16:03:16 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070513160316-2h6kn6h1z0q1fvyo
Tags: 3.0.PRE6-1
* New upstream release
  - Removed patches integrated upsteam:
    + 04-m68k-ftbfs

* debian/rules
  - Enable delay pools (Closes: #410785)
  - Enable cache digests (Closes: #416631)
  - Enable ICAP client
  - Raised Max Filedescriptor limit to 65536

* debian/control
  - Added real package dependency for httpd in squid3-cgi

* debian/patches/02-makefile-defaults
  - Fix default configuration file for cachemgr.cgi (Closes: #416630)

* debian/squid3.postinst
  - Fixed bashish in postinst (Closes: #411797)

* debian/patches/05-helpers-typo
  - Added upstream patch fixing compilation error in src/helpers.cc

* debian/patches/06-mem-obj-reference
  - Added upstream patch fixing a mem_obj reference in src/store.cc

* debian/patches/07-close-icap-connections
  - Added upstream patch fixing icap connection starvation

* debian/squid3.rc
  - Added LSB-compliant description to rc script

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
/*
3
 
 * $Id: store_digest.cc,v 1.70 2006/08/21 00:50:41 robertc Exp $
 
3
 * $Id: store_digest.cc,v 1.75 2007/04/30 16:56:09 wessels Exp $
4
4
 *
5
5
 * DEBUG: section 71    Store Digest Manager
6
6
 * AUTHOR: Alex Rousskov
115
115
 
116
116
    if (!Config.onoff.digest_generation) {
117
117
        store_digest = NULL;
118
 
        debug(71, 3) ("Local cache digest generation disabled\n");
 
118
        debugs(71, 3, "Local cache digest generation disabled");
119
119
        return;
120
120
    }
121
121
 
122
122
    store_digest = cacheDigestCreate(cap, Config.digest.bits_per_entry);
123
 
    debug(71, 1) ("Local cache digest enabled; rebuild/rewrite every %d/%d sec\n",
124
 
                  (int) Config.digest.rebuild_period, (int) Config.digest.rewrite_period);
 
123
    debugs(71, 1, "Local cache digest enabled; rebuild/rewrite every " <<
 
124
           (int) Config.digest.rebuild_period << "/" <<
 
125
           (int) Config.digest.rewrite_period << " sec");
 
126
 
125
127
    memset(&sd_state, 0, sizeof(sd_state));
126
128
#else
127
129
 
128
130
    store_digest = NULL;
129
 
    debug(71, 3) ("Local cache digest is 'off'\n");
 
131
    debugs(71, 3, "Local cache digest is 'off'");
130
132
#endif
131
133
}
132
134
 
161
163
    }
162
164
 
163
165
    assert(entry && store_digest);
164
 
    debug(71, 6) ("storeDigestDel: checking entry, key: %s\n",
165
 
                  entry->getMD5Text());
 
166
    debugs(71, 6, "storeDigestDel: checking entry, key: " << entry->getMD5Text());
166
167
 
167
168
    if (!EBIT_TEST(entry->flags, KEY_PRIVATE)) {
168
169
        if (!cacheDigestTest(store_digest,  (const cache_key *)entry->key)) {
169
170
            sd_stats.del_lost_count++;
170
 
            debug(71, 6) ("storeDigestDel: lost entry, key: %s url: %s\n",
171
 
                          entry->getMD5Text(), storeUrl(entry));
 
171
            debugs(71, 6, "storeDigestDel: lost entry, key: " << entry->getMD5Text() << " url: " << entry->url()  );
172
172
        } else {
173
173
            sd_stats.del_count++;
174
174
            cacheDigestDel(store_digest,  (const cache_key *)entry->key);
175
 
            debug(71, 6) ("storeDigestDel: deled entry, key: %s\n",
176
 
                          entry->getMD5Text());
 
175
            debugs(71, 6, "storeDigestDel: deled entry, key: " << entry->getMD5Text());
177
176
        }
178
177
    }
179
178
 
218
217
{
219
218
    /* add some stats! XXX */
220
219
 
221
 
    debug(71, 6) ("storeDigestAddable: checking entry, key: %s\n",
222
 
                  e->getMD5Text());
 
220
    debugs(71, 6, "storeDigestAddable: checking entry, key: " << e->getMD5Text());
223
221
 
224
 
    /* check various entry flags (mimics storeCheckCachable XXX) */
 
222
    /* check various entry flags (mimics StoreEntry::checkCachable XXX) */
225
223
 
226
224
    if (!EBIT_TEST(e->flags, ENTRY_CACHABLE)) {
227
 
        debug(71, 6) ("storeDigestAddable: NO: not cachable\n");
 
225
        debugs(71, 6, "storeDigestAddable: NO: not cachable");
228
226
        return 0;
229
227
    }
230
228
 
231
229
    if (EBIT_TEST(e->flags, KEY_PRIVATE)) {
232
 
        debug(71, 6) ("storeDigestAddable: NO: private key\n");
 
230
        debugs(71, 6, "storeDigestAddable: NO: private key");
233
231
        return 0;
234
232
    }
235
233
 
236
234
    if (EBIT_TEST(e->flags, ENTRY_NEGCACHED)) {
237
 
        debug(71, 6) ("storeDigestAddable: NO: negative cached\n");
 
235
        debugs(71, 6, "storeDigestAddable: NO: negative cached");
238
236
        return 0;
239
237
    }
240
238
 
241
239
    if (EBIT_TEST(e->flags, RELEASE_REQUEST)) {
242
 
        debug(71, 6) ("storeDigestAddable: NO: release requested\n");
 
240
        debugs(71, 6, "storeDigestAddable: NO: release requested");
243
241
        return 0;
244
242
    }
245
243
 
246
244
    if (e->store_status == STORE_OK && EBIT_TEST(e->flags, ENTRY_BAD_LENGTH)) {
247
 
        debug(71, 6) ("storeDigestAddable: NO: wrong content-length\n");
 
245
        debugs(71, 6, "storeDigestAddable: NO: wrong content-length");
248
246
        return 0;
249
247
    }
250
248
 
251
249
    /* do not digest huge objects */
252
250
    if (e->swap_file_sz > Config.Store.maxObjectSize) {
253
 
        debug(71, 6) ("storeDigestAddable: NO: too big\n");
 
251
        debugs(71, 6, "storeDigestAddable: NO: too big");
254
252
        return 0;
255
253
    }
256
254
 
257
255
    /* still here? check staleness */
258
256
    /* Note: We should use the time of the next rebuild, not (cur_time+period) */
259
257
    if (refreshCheckDigest(e, Config.digest.rebuild_period)) {
260
 
        debug(71, 6) ("storeDigestAdd: entry expires within %d secs, ignoring\n",
261
 
                      (int) Config.digest.rebuild_period);
 
258
        debugs(71, 6, "storeDigestAdd: entry expires within " << Config.digest.rebuild_period << " secs, ignoring");
262
259
        return 0;
263
260
    }
264
261
 
271
268
     * idea: skip objects that are going to be purged before the next
272
269
     * update.
273
270
     */
274
 
#if OLD_UNUSED_CODE             /* This code isn't applicable anymore, we can't fix it atm either :( */
275
 
    if ((squid_curtime + Config.digest.rebuild_period) - e->lastref > storeExpiredReferenceAge())
276
 
        return 0;
277
 
 
278
 
#endif
279
 
 
280
271
    return 1;
281
272
}
282
273
 
293
284
 
294
285
        cacheDigestAdd(store_digest,  (const cache_key *)entry->key);
295
286
 
296
 
        debug(71, 6) ("storeDigestAdd: added entry, key: %s\n",
297
 
                      entry->getMD5Text());
 
287
        debugs(71, 6, "storeDigestAdd: added entry, key: " << entry->getMD5Text());
298
288
    } else {
299
289
        sd_stats.rej_count++;
300
290
 
311
301
    /* prevent overlapping if rebuild schedule is too tight */
312
302
 
313
303
    if (sd_state.rebuild_lock) {
314
 
        debug(71, 1) ("storeDigestRebuildStart: overlap detected, consider increasing rebuild period\n");
 
304
        debugs(71, 1, "storeDigestRebuildStart: overlap detected, consider increasing rebuild period");
315
305
        return;
316
306
    }
317
307
 
318
308
    sd_state.rebuild_lock = 1;
319
 
    debug(71, 2) ("storeDigestRebuildStart: rebuild #%d\n", sd_state.rebuild_count + 1);
 
309
    debugs(71, 2, "storeDigestRebuildStart: rebuild #" << sd_state.rebuild_count + 1);
320
310
 
321
311
    if (sd_state.rewrite_lock) {
322
 
        debug(71, 2) ("storeDigestRebuildStart: waiting for Rewrite to finish.\n");
 
312
        debugs(71, 2, "storeDigestRebuildStart: waiting for Rewrite to finish.");
323
313
        return;
324
314
    }
325
315
 
350
340
    assert(sd_state.rebuild_lock);
351
341
    sd_state.rebuild_lock = 0;
352
342
    sd_state.rebuild_count++;
353
 
    debug(71, 2) ("storeDigestRebuildFinish: done.\n");
 
343
    debugs(71, 2, "storeDigestRebuildFinish: done.");
354
344
    eventAdd("storeDigestRebuildStart", storeDigestRebuildStart, NULL, (double)
355
345
             Config.digest.rebuild_period, 1);
356
346
    /* resume pending Rewrite if any */
368
358
                (double) Config.digest.rebuild_chunk_percentage / 100.0);
369
359
    assert(sd_state.rebuild_lock);
370
360
 
371
 
    debug(71, 3) ("storeDigestRebuildStep: buckets: %d entries to check: %d\n",
372
 
                  store_hash_buckets, count);
 
361
    debugs(71, 3, "storeDigestRebuildStep: buckets: " << store_hash_buckets << " entries to check: " << count);
373
362
 
374
363
    while (count-- && !sd_state.theSearch->isDone() && sd_state.theSearch->next())
375
364
        storeDigestAdd(sd_state.theSearch->currentItem());
394
383
    /* prevent overlapping if rewrite schedule is too tight */
395
384
 
396
385
    if (sd_state.rewrite_lock) {
397
 
        debug(71, 1) ("storeDigestRewrite: overlap detected, consider increasing rewrite period\n");
 
386
        debugs(71, 1, "storeDigestRewrite: overlap detected, consider increasing rewrite period");
398
387
        return;
399
388
    }
400
389
 
401
 
    debug(71, 2) ("storeDigestRewrite: start rewrite #%d\n", sd_state.rewrite_count + 1);
 
390
    debugs(71, 2, "storeDigestRewrite: start rewrite #" << sd_state.rewrite_count + 1);
402
391
    /* make new store entry */
403
392
    url = internalLocalUri("/squid-internal-periodic/", StoreDigestFileName);
404
393
    flags.cachable = 1;
405
394
    e = storeCreateEntry(url, url, flags, METHOD_GET);
406
395
    assert(e);
407
396
    sd_state.rewrite_lock = e;
408
 
    debug(71, 3) ("storeDigestRewrite: url: %s key: %s\n", url, e->getMD5Text());
 
397
    debugs(71, 3, "storeDigestRewrite: url: " << url << " key: " << e->getMD5Text());
409
398
    HttpRequest *req = HttpRequest::CreateFromUrl(url);
410
399
    e->mem_obj->request = HTTPMSGLOCK(req);
411
400
    /* wait for rebuild (if any) to finish */
412
401
 
413
402
    if (sd_state.rebuild_lock) {
414
 
        debug(71, 2) ("storeDigestRewriteStart: waiting for rebuild to finish.\n");
 
403
        debugs(71, 2, "storeDigestRewriteStart: waiting for rebuild to finish.");
415
404
        return;
416
405
    }
417
406
 
429
418
    sd_state.rewrite_offset = 0;
430
419
    EBIT_SET(e->flags, ENTRY_SPECIAL);
431
420
    /* setting public key will purge old digest entry if any */
432
 
    storeSetPublicKey(e);
 
421
    e->setPublicKey();
433
422
    /* fake reply */
434
423
    HttpReply *rep = new HttpReply;
435
424
    HttpVersion version(1, 0);
436
425
    rep->setHeaders(version, HTTP_OK, "Cache Digest OK",
437
426
                    "application/cache-digest", store_digest->mask_size + sizeof(sd_state.cblock),
438
427
                    squid_curtime, squid_curtime + Config.digest.rewrite_period);
439
 
    debug(71, 3) ("storeDigestRewrite: entry expires on %ld (%+d)\n",
440
 
                  (long int) rep->expires, (int) (rep->expires - squid_curtime));
441
 
    storeBuffer(e);
 
428
    debugs(71, 3, "storeDigestRewrite: entry expires on " << rep->expires << 
 
429
           " (" << std::showpos << (int) (rep->expires - squid_curtime) << ")");
 
430
    e->buffer();
442
431
    e->replaceHttpReply(rep);
443
432
    storeDigestCBlockSwapOut(e);
444
 
    storeBufferFlush(e);
 
433
    e->flush();
445
434
    eventAdd("storeDigestSwapOutStep", storeDigestSwapOutStep, sd_state.rewrite_lock, 0.0, 1, false);
446
435
}
447
436
 
451
440
{
452
441
    assert(e == sd_state.rewrite_lock);
453
442
    e->complete();
454
 
    storeTimestampsSet(e);
455
 
    debug(71, 2) ("storeDigestRewriteFinish: digest expires at %ld (%+d)\n",
456
 
                  (long int) e->expires, (int) (e->expires - squid_curtime));
 
443
    e->timestampsSet();
 
444
    debugs(71, 2, "storeDigestRewriteFinish: digest expires at " << e->expires << 
 
445
           " (" << std::showpos << (int) (e->expires - squid_curtime) << ")");
457
446
    /* is this the write order? @?@ */
458
447
    e->mem_obj->unlinkRequest();
459
448
    e->unlock();
480
469
    if ((size_t)(sd_state.rewrite_offset + chunk_size) > store_digest->mask_size)
481
470
        chunk_size = store_digest->mask_size - sd_state.rewrite_offset;
482
471
 
483
 
    storeAppend(e, store_digest->mask + sd_state.rewrite_offset, chunk_size);
 
472
    e->append(store_digest->mask + sd_state.rewrite_offset, chunk_size);
484
473
 
485
474
    debugs(71, 3, "storeDigestSwapOutStep: size: " << store_digest->mask_size <<
486
475
           " offset: " << sd_state.rewrite_offset << " chunk: " <<
508
497
    sd_state.cblock.bits_per_entry = (unsigned char)
509
498
                                     Config.digest.bits_per_entry;
510
499
    sd_state.cblock.hash_func_count = (unsigned char) CacheDigestHashFuncCount;
511
 
    storeAppend(e, (char *) &sd_state.cblock, sizeof(sd_state.cblock));
 
500
    e->append((char *) &sd_state.cblock, sizeof(sd_state.cblock));
512
501
}
513
502
 
514
503
/* calculates digest capacity */
524
513
    const int lo_cap = 1 + store_swap_size / Config.Store.avgObjectSize;
525
514
    const int e_count = StoreEntry::inUseCount();
526
515
    int cap = e_count ? e_count : hi_cap;
527
 
    debug(71, 2) ("storeDigestCalcCap: have: %d, want %d entries; limits: [%d, %d]\n",
528
 
                  e_count, cap, lo_cap, hi_cap);
 
516
    debugs(71, 2, "storeDigestCalcCap: have: " << e_count << ", want " << cap <<
 
517
           " entries; limits: [" << lo_cap << ", " << hi_cap << "]");
529
518
 
530
519
    if (cap < lo_cap)
531
520
        cap = lo_cap;
545
534
    int diff;
546
535
    assert(store_digest);
547
536
    diff = abs(cap - store_digest->capacity);
548
 
    debug(71, 2) ("storeDigestResize: %d -> %d; change: %d (%d%%)\n",
549
 
                  store_digest->capacity, cap, diff,
550
 
                  xpercentInt(diff, store_digest->capacity));
 
537
    debugs(71, 2, "storeDigestResize: " << 
 
538
           store_digest->capacity << " -> " << cap << "; change: " << 
 
539
           diff << " (" << xpercentInt(diff, store_digest->capacity) << "%)" );
551
540
    /* avoid minor adjustments */
552
541
 
553
542
    if (diff <= store_digest->capacity / 10) {
554
 
        debug(71, 2) ("storeDigestResize: small change, will not resize.\n");
 
543
        debugs(71, 2, "storeDigestResize: small change, will not resize.");
555
544
        return 0;
556
545
    } else {
557
 
        debug(71, 2) ("storeDigestResize: big change, resizing.\n");
 
546
        debugs(71, 2, "storeDigestResize: big change, resizing.");
558
547
        cacheDigestChangeCap(store_digest, cap);
559
548
        return 1;
560
549
    }