Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions src/iocore/cache/CacheProcessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ void register_cache_stats(CacheStatsBlock *rsb, const std::string &pre
static void cplist_update();
static int create_volume(int volume_number, off_t size_in_blocks, CacheType scheme, CacheVol *cp);
static int fillExclusiveDisks(CacheVol *cp);
static void cplist_apply_config_settings(CacheVol *cp, const ConfigVol *config_vol);

static size_t DEFAULT_RAM_CACHE_MULTIPLIER = 10; // I.e. 10x 1MB per 1GB of disk.

Expand Down Expand Up @@ -1038,6 +1039,14 @@ cplist_reconfigure()
}
}

// Apply per-volume settings after all CacheVols exist; otherwise volumes created on the first
// start after a cache clear keep defaults and ignore the config until the next restart.
for (ConfigVol *config_vol = config_volumes.cp_queue.head; config_vol; config_vol = config_vol->link.next) {
if (config_vol->cachep) {
cplist_apply_config_settings(config_vol->cachep, config_vol);
}
}

ts::Metrics::Gauge::store(cache_rsb.stripes, gnstripes);

return 0;
Expand Down Expand Up @@ -1154,6 +1163,17 @@ register_cache_stats(CacheStatsBlock *rsb, const std::string &prefix)
rsb->writer_lock_contention = ts::Metrics::Counter::createPtr(prefix + ".writer.lock_contention");
}

// Copy the per-volume tuning fields from the volume config onto the CacheVol.
void
cplist_apply_config_settings(CacheVol *cp, const ConfigVol *config_vol)
{
cp->ramcache_enabled = config_vol->ramcache_enabled;
cp->avg_obj_size = config_vol->avg_obj_size;
cp->fragment_size = config_vol->fragment_size;
cp->ram_cache_size = config_vol->ram_cache_size;
cp->ram_cache_cutoff = config_vol->ram_cache_cutoff;
}

void
cplist_update()
{
Expand All @@ -1165,12 +1185,7 @@ cplist_update()
for (config_vol = config_volumes.cp_queue.head; config_vol; config_vol = config_vol->link.next) {
if (config_vol->number == cp->vol_number) {
if (cp->scheme == config_vol->scheme) {
cp->ramcache_enabled = config_vol->ramcache_enabled;
cp->avg_obj_size = config_vol->avg_obj_size;
cp->fragment_size = config_vol->fragment_size;
cp->ram_cache_size = config_vol->ram_cache_size;
cp->ram_cache_cutoff = config_vol->ram_cache_cutoff;
config_vol->cachep = cp;
config_vol->cachep = cp;
} else {
/* delete this volume from all the disks */
int d_no;
Expand Down
20 changes: 16 additions & 4 deletions tests/gold_tests/cache/cache_volume_features.replay.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,24 @@ meta:
version: "1.0"

# This test proves that multi-parameter volume.config lines are parsed
# correctly. The generated volume.config lines are:
# correctly AND that the per-volume settings actually take effect on the first
# start after a cache clear (AuTest always starts ATS against a fresh cache).
# The generated volume.config lines are:
#
# volume=1 scheme=http size=50% ram_cache_size=32M ram_cache_cutoff=8K
# volume=2 scheme=http size=50%
# volume=1 scheme=http size=50% ram_cache_size=32M ram_cache_cutoff=8K avg_obj_size=2000 fragment_size=1M
# volume=2 scheme=http size=50% ramcache=false
#
# All 5 key=value pairs on line 1 must be parsed from the single line.
# If the inner loop's "tmp = line_end" advancement were broken (as claimed
# in a PR review), only "volume=1" would be parsed, scheme and size would
# be missing, and the volume would be rejected -- disabling the cache.
# be missing, and the volume would be rejected -- disabling the cache, and the
# per-volume settings are verified via the metric_checks below:
# - Volume 1 (ram_cache_size: 32M, single 128MB stripe) -> ram_cache total_bytes == 32MB
# - Volume 1 (avg_obj_size: 2000) -> direntries.total == 66424
# - Volume 2 (ramcache: false) -> ram_cache total_bytes == 0
# These exercise two distinct downstream paths (the RAM cache sizing in
# cacheInitialized() and the directory sizing in the StripeSM constructor). On a
# build that ignores per-volume settings on first start, none of them match.
autest:
description: "Test cache volume features: per-volume RAM cache and @volume= directive"

Expand Down Expand Up @@ -57,10 +66,13 @@ autest:
size: "50%"
ram_cache_size: "32M"
ram_cache_cutoff: "8K"
avg_obj_size: 2000
fragment_size: 1M
# Volume 2 — simple line, no extra params
- volume: 2
scheme: "http"
size: "50%"
ramcache: false

log_validation:
traffic_out:
Expand Down
3 changes: 2 additions & 1 deletion tests/gold_tests/cache/cache_volume_features.test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

Test.Summary = '''
Comprehensive test suite for cache volume features:
- Per-volume RAM cache configuration (ram_cache_size, ram_cache_cutoff)
- Per-volume RAM cache configuration (ram_cache, ram_cache_size, ram_cache_cutoff)
- Per-volume settings take effect on the first start after a cache clear
- @volume= directive in remap.config for volume selection
- Integration between both features
'''
Expand Down