Skip to content

Commit 88d3b83

Browse files
committed
CoPilot Review fixes
1 parent 02244cd commit 88d3b83

File tree

7 files changed

+156
-52
lines changed

7 files changed

+156
-52
lines changed

doc/admin-guide/files/volume.config.en.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ for a smaller, or larger, fragment size for a particular volume. This may be
8989
useful together with ``avg_obj_size`` as well, since a larger fragment size could
9090
reduce the number of directory entries needed for a large object.
9191

92-
Note that this setting has a maximmum value of 4MB.
92+
Note that this setting has a maximum value of 4MB.
9393

9494
Optional RAM cache size allocation
9595
-----------------------------------

src/iocore/cache/Cache.cc

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ Cache::open_done()
231231
}
232232

233233
ReplaceablePtr<CacheHostTable>::ScopedReader hosttable(&this->hosttable);
234-
if (hosttable->gen_host_rec.num_cachevols == 0) {
234+
if (hosttable->getGenHostRecCacheVols() == 0) {
235235
ready = CacheInitState::FAILED;
236236
} else {
237237
ready = CacheInitState::INITIALIZED;
@@ -750,34 +750,27 @@ Cache::key_to_stripe(const CacheKey *key, std::string_view hostname, int volume_
750750
ReplaceablePtr<CacheHostTable>::ScopedReader hosttable(&this->hosttable);
751751

752752
uint32_t h = (key->slice32(2) >> DIR_TAG_WIDTH) % STRIPE_HASH_TABLE_SIZE;
753-
unsigned short *hash_table = hosttable->gen_host_rec.vol_hash_table;
754-
const CacheHostRecord *host_rec = &hosttable->gen_host_rec;
753+
const CacheHostRecord *host_rec = hosttable->getGenHostRec();
754+
unsigned short *hash_table = host_rec->vol_hash_table;
755755
StripeSM *selected_stripe = nullptr;
756756
bool remap_selection = false;
757757

758758
if (volume_override > 0) {
759-
for (int i = 0; i < host_rec->num_cachevols; i++) {
760-
if (host_rec->cp[i] && host_rec->cp[i]->vol_number == volume_override) {
761-
for (int j = 0; j < host_rec->num_vols; j++) {
762-
if (host_rec->stripes[j] && host_rec->stripes[j]->cache_vol &&
763-
host_rec->stripes[j]->cache_vol->vol_number == volume_override) {
764-
selected_stripe = host_rec->stripes[j];
765-
remap_selection = true;
766-
break;
767-
}
768-
}
769-
break;
770-
}
771-
}
759+
CacheVol *target_vol = hosttable->getVolumeByNumber(volume_override);
760+
761+
if (target_vol && target_vol->stripes && target_vol->num_vols > 0) {
762+
int volume_stripe = h % target_vol->num_vols;
772763

773-
if (!selected_stripe) {
774-
Warning("Invalid volume override %d, volume configured but no stripes available. Falling back to hostname-based selection.",
775-
volume_override);
764+
selected_stripe = target_vol->stripes[volume_stripe];
765+
remap_selection = true;
766+
Dbg(dbg_ctl_cache_hosting, "Volume override %d: stripe %d (hash-based)", volume_override, volume_stripe);
767+
} else {
768+
Dbg(dbg_ctl_cache_hosting, "Volume override %d: not found, using default selection", volume_override);
776769
}
777770
}
778771

779772
// Normal hostname-based volume selection (if no valid override)
780-
if (!selected_stripe && hosttable->m_numEntries > 0 && !hostname.empty()) {
773+
if (!selected_stripe && hosttable->getNumEntries() > 0 && !hostname.empty()) {
781774
CacheHostResult res;
782775

783776
hosttable->Match(hostname, &res);

src/iocore/cache/CacheHosting.cc

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ namespace
3838
DbgCtl dbg_ctl_cache_hosting{"cache_hosting"};
3939
DbgCtl dbg_ctl_matcher{"matcher"};
4040

41+
// Use same constant as defined in traffic_cache_tool/CacheDefs.h
42+
constexpr static int MAX_VOLUME_IDX = 255;
43+
4144
} // end anonymous namespace
4245

4346
/*************************************************************
@@ -227,6 +230,22 @@ CacheHostTable::Match(std::string_view rdata, CacheHostResult *result) const
227230
hostMatch->Match(rdata, result);
228231
}
229232

233+
CacheVol *
234+
CacheHostTable::getVolumeByNumber(int volume_num) const
235+
{
236+
if (volume_num < 1 || volume_num > MAX_VOLUME_IDX) {
237+
return nullptr;
238+
}
239+
240+
for (int i = 0; i < gen_host_rec.num_cachevols; i++) {
241+
if (gen_host_rec.cp[i] && gen_host_rec.cp[i]->vol_number == volume_num) {
242+
return gen_host_rec.cp[i];
243+
}
244+
}
245+
246+
return nullptr;
247+
}
248+
230249
int
231250
CacheHostTable::config_callback(const char * /* name ATS_UNUSED */, RecDataT /* data_type ATS_UNUSED */,
232251
RecData /* data ATS_UNUSED */, void *cookie)
@@ -614,6 +633,17 @@ ConfigVolumes::read_config_file()
614633
return;
615634
}
616635

636+
bool
637+
ConfigVolumes::volume_number_exists(int vol_number) const
638+
{
639+
for (ConfigVol *config_vol = cp_queue.head; config_vol; config_vol = config_vol->link.next) {
640+
if (config_vol->number == vol_number) {
641+
return true;
642+
}
643+
}
644+
return false;
645+
}
646+
617647
void
618648
ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf)
619649
{
@@ -698,7 +728,7 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf)
698728
break;
699729
}
700730

701-
if (volume_number < 1 || volume_number > 255) {
731+
if (volume_number < 1 || volume_number > MAX_VOLUME_IDX) {
702732
err = "Bad Volume Number";
703733
break;
704734
}
@@ -742,8 +772,12 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf)
742772
in_percent = 0;
743773
}
744774
} else if (strcasecmp(tmp, "avg_obj_size") == 0) { // match avg_obj_size
745-
tmp += 13;
746-
avg_obj_size = static_cast<int>(ink_atoi64(tmp));
775+
tmp += 13;
776+
if (!ParseRules::is_digit(*tmp)) {
777+
err = "Invalid avg_obj_size value (must start with a number, e.g., 64K)";
778+
break;
779+
}
780+
avg_obj_size = static_cast<int>(ink_atoi64(tmp));
747781

748782
if (avg_obj_size < 0) {
749783
err = "Invalid avg_obj_size value (must be >= 0)";
@@ -753,8 +787,12 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf)
753787
tmp++;
754788
}
755789
} else if (strcasecmp(tmp, "fragment_size") == 0) { // match fragment_size
756-
tmp += 14;
757-
fragment_size = static_cast<int>(ink_atoi64(tmp));
790+
tmp += 14;
791+
if (!ParseRules::is_digit(*tmp)) {
792+
err = "Invalid fragment_size value (must start with a number, e.g., 1M)";
793+
break;
794+
}
795+
fragment_size = static_cast<int>(ink_atoi64(tmp));
758796

759797
if (fragment_size < 0) {
760798
err = "Invalid fragment_size value (must be >= 0)";
@@ -776,8 +814,12 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf)
776814
break;
777815
}
778816
} else if (strcasecmp(tmp, "ram_cache_size") == 0) { // match ram_cache_size
779-
tmp += 15;
780-
ram_cache_size = ink_atoi64(tmp);
817+
tmp += 15;
818+
if (!ParseRules::is_digit(*tmp)) {
819+
err = "Invalid ram_cache_size value (must start with a number, e.g., 10G)";
820+
break;
821+
}
822+
ram_cache_size = ink_atoi64(tmp);
781823

782824
if (ram_cache_size < 0) {
783825
err = "Invalid ram_cache_size value (must be >= 0)";
@@ -788,8 +830,12 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf)
788830
tmp++;
789831
}
790832
} else if (strcasecmp(tmp, "ram_cache_cutoff") == 0) { // match ram_cache_cutoff
791-
tmp += 17;
792-
ram_cache_cutoff = ink_atoi64(tmp);
833+
tmp += 17;
834+
if (!ParseRules::is_digit(*tmp)) {
835+
err = "Invalid ram_cache_cutoff value (must start with a number, e.g., 5M)";
836+
break;
837+
}
838+
ram_cache_cutoff = ink_atoi64(tmp);
793839

794840
if (ram_cache_cutoff < 0) {
795841
err = "Invalid ram_cache_cutoff value (must be >= 0)";
@@ -802,7 +848,7 @@ ConfigVolumes::BuildListFromString(char *config_file_path, char *file_buf)
802848

803849
// ends here
804850
if (end < line_end) {
805-
tmp++;
851+
tmp = line_end;
806852
}
807853
}
808854

src/iocore/cache/CacheProcessor.cc

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ CacheProcessor::mark_storage_offline(CacheDisk *d, ///< Target disk
487487
} else { // check cache types specifically
488488
if (theCache) {
489489
ReplaceablePtr<CacheHostTable>::ScopedReader hosttable(&theCache->hosttable);
490-
if (!hosttable->gen_host_rec.vol_hash_table) {
490+
if (!hosttable->getGenHostRec()->vol_hash_table) {
491491
unsigned int caches_ready = 0;
492492
caches_ready = caches_ready | (1 << CACHE_FRAG_TYPE_HTTP);
493493
caches_ready = caches_ready | (1 << CACHE_FRAG_TYPE_NONE);
@@ -510,8 +510,8 @@ void
510510
rebuild_host_table(Cache *cache)
511511
{
512512
ReplaceablePtr<CacheHostTable>::ScopedWriter hosttable(&cache->hosttable);
513-
build_vol_hash_table(&hosttable->gen_host_rec);
514-
if (hosttable->m_numEntries != 0) {
513+
build_vol_hash_table(const_cast<CacheHostRecord *>(hosttable->getGenHostRec()));
514+
if (hosttable->getNumEntries() != 0) {
515515
CacheHostMatcher *hm = hosttable->getHostMatcher();
516516
CacheHostRecord *h_rec = hm->getDataArray();
517517
int h_rec_len = hm->getNumElements();
@@ -1480,8 +1480,13 @@ CacheProcessor::cacheInitialized()
14801480
Warning("Total private RAM cache allocations (%" PRId64 " bytes) exceed global ram_cache.size (%" PRId64 " bytes). "
14811481
"Using global limit. Consider increasing proxy.config.cache.ram_cache.size.",
14821482
total_private_ram, cache_config_ram_cache_size);
1483-
shared_pool = cache_config_ram_cache_size; // Fall back to using the global pool for all
1484-
total_private_ram = 0; // Disable private allocations
1483+
shared_pool = cache_config_ram_cache_size; // Fall back to using the global pool for all
1484+
1485+
CacheVol *cp = cp_list.head;
1486+
1487+
for (; cp; cp = cp->link.next) {
1488+
cp->ram_cache_size = 0;
1489+
}
14851490
} else if (total_private_ram > 0) {
14861491
Dbg(dbg_ctl_cache_init, "Shared RAM cache pool (after private allocations): %" PRId64 " bytes (%" PRId64 " MB)",
14871492
shared_pool, shared_pool / (1024 * 1024));
@@ -1542,12 +1547,17 @@ CacheProcessor::cacheInitialized()
15421547
ram_cache_bytes = stripe->dirlen() * DEFAULT_RAM_CACHE_MULTIPLIER;
15431548
} else {
15441549
// Use shared pool allocation - distribute only among volumes without explicit allocations
1545-
ink_assert(stripe->cache != nullptr);
1546-
int64_t divisor = (shared_cache_size > 0) ? shared_cache_size : theCache->cache_size;
1547-
double factor = static_cast<double>(static_cast<int64_t>(stripe->len >> STORE_BLOCK_SHIFT)) / divisor;
1548-
1549-
Dbg(dbg_ctl_cache_init, "factor = %f (divisor = %" PRId64 ")", factor, divisor);
1550-
ram_cache_bytes = static_cast<int64_t>(http_ram_cache_size * factor);
1550+
if (shared_cache_size > 0) {
1551+
ink_assert(stripe->cache != nullptr);
1552+
double factor = static_cast<double>(static_cast<int64_t>(stripe->len >> STORE_BLOCK_SHIFT)) / shared_cache_size;
1553+
1554+
Dbg(dbg_ctl_cache_init, "factor = %f (divisor = %" PRId64 ")", factor, shared_cache_size);
1555+
ram_cache_bytes = static_cast<int64_t>(http_ram_cache_size * factor);
1556+
} else {
1557+
ram_cache_bytes = 0;
1558+
Dbg(dbg_ctl_cache_init, "Volume %d stripe has no explicit RAM allocation, but shared pool is empty",
1559+
stripe->cache_vol->vol_number);
1560+
}
15511561
}
15521562

15531563
stripe->ram_cache->init(ram_cache_bytes, stripe);

src/iocore/cache/CacheVC.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ CacheVC::scanStripe(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */)
637637

638638
ReplaceablePtr<CacheHostTable>::ScopedReader hosttable(&theCache->hosttable);
639639

640-
const CacheHostRecord *rec = &hosttable->gen_host_rec;
640+
const CacheHostRecord *rec = hosttable->getGenHostRec();
641641
if (!hostname.empty()) {
642642
CacheHostResult res;
643643
hosttable->Match(hostname, &res);

src/iocore/cache/P_CacheHosting.h

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,25 +229,60 @@ class CacheHostTable
229229
void Match(std::string_view rdata, CacheHostResult *result) const;
230230
void Print() const;
231231

232+
// Simple volume lookup for @volume= directive support
233+
CacheVol *getVolumeByNumber(int volume_num) const;
234+
235+
// Getters for Cache::key_to_stripe access
236+
const CacheHostRecord *
237+
getGenHostRec() const
238+
{
239+
return &gen_host_rec;
240+
}
232241
int
233-
getEntryCount() const
242+
getNumEntries() const
234243
{
235244
return m_numEntries;
236245
}
246+
247+
int
248+
getGenHostRecCacheVols() const
249+
{
250+
return gen_host_rec.num_cachevols;
251+
}
252+
237253
CacheHostMatcher *
238254
getHostMatcher() const
239255
{
240256
return hostMatch.get();
241257
}
242258

243-
static int config_callback(const char *, RecDataT, RecData, void *);
259+
CacheType
260+
getType() const
261+
{
262+
return type;
263+
}
264+
265+
Cache *
266+
getCache() const
267+
{
268+
return cache;
269+
}
244270

245271
void
246272
register_config_callback(ReplaceablePtr<CacheHostTable> *p)
247273
{
248274
RecRegisterConfigUpdateCb("proxy.config.cache.hosting_filename", CacheHostTable::config_callback, (void *)p);
249275
}
250276

277+
private:
278+
int
279+
getEntryCount() const
280+
{
281+
return m_numEntries;
282+
}
283+
284+
static int config_callback(const char *, RecDataT, RecData, void *);
285+
251286
CacheType type = CacheType::HTTP;
252287
Cache *cache = nullptr;
253288
int m_numEntries = 0;
@@ -276,8 +311,8 @@ struct CacheHostTableConfig : public Continuation {
276311
Cache *cache = nullptr;
277312
{
278313
ReplaceablePtr<CacheHostTable>::ScopedReader hosttable(ppt);
279-
type = hosttable->type;
280-
cache = hosttable->cache;
314+
type = hosttable->getType();
315+
cache = hosttable->getCache();
281316
}
282317
ppt->reset(new CacheHostTable(cache, type));
283318
delete this;
@@ -310,6 +345,7 @@ struct ConfigVolumes {
310345
Queue<ConfigVol> cp_queue;
311346
void read_config_file();
312347
void BuildListFromString(char *config_file_path, char *file_buf);
348+
bool volume_number_exists(int vol_number) const;
313349

314350
void
315351
clear_all()

src/proxy/http/remap/RemapConfig.cc

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,22 @@ using namespace std::literals;
4343

4444
load_remap_file_func load_remap_file_cb = nullptr;
4545

46+
// Forward declaration and external reference for volume validation
47+
class ConfigVolumes
48+
{
49+
public:
50+
bool volume_number_exists(int volume_num) const;
51+
};
52+
extern ConfigVolumes config_volumes;
53+
4654
namespace
4755
{
4856
DbgCtl dbg_ctl_url_rewrite{"url_rewrite"};
4957
DbgCtl dbg_ctl_remap_plugin{"remap_plugin"};
5058
DbgCtl dbg_ctl_url_rewrite_regex{"url_rewrite_regex"};
59+
60+
// Use same constant as defined in src/iocore/cache/CacheHosting.cc
61+
constexpr static int MAX_VOLUME_IDX = 255;
5162
} // end anonymous namespace
5263

5364
/**
@@ -1220,14 +1231,22 @@ remap_parse_config_bti(const char *path, BUILD_TABLE_INFO *bti)
12201231
int ret = remap_check_option(bti->argv, bti->argc, REMAP_OPTFLG_VOLUME, &idx);
12211232

12221233
if (ret & REMAP_OPTFLG_VOLUME) {
1223-
char *c = strchr(bti->argv[idx], static_cast<int>('='));
1224-
int volume_num = atoi(++c);
1234+
int volume_num = atoi(&bti->argv[idx][7]);
12251235

12261236
new_mapping->cache_volume = volume_num;
12271237

1228-
// Validate volume number (basic validation - detailed validation later)
1229-
if (volume_num < 1) {
1230-
snprintf(errStrBuf, sizeof(errStrBuf), "Invalid cache volume number %d at line %d (must be >= 1)", volume_num, cln + 1);
1238+
// Validate volume number
1239+
if (volume_num < 1 || volume_num > MAX_VOLUME_IDX) {
1240+
snprintf(errStrBuf, sizeof(errStrBuf), "Invalid cache volume number %d at line %d (must be between 1 and %d)", volume_num,
1241+
cln + 1, MAX_VOLUME_IDX);
1242+
errStr = errStrBuf;
1243+
goto MAP_ERROR;
1244+
}
1245+
1246+
// Validate that the volume exists in volume.config
1247+
if (!config_volumes.volume_number_exists(volume_num)) {
1248+
snprintf(errStrBuf, sizeof(errStrBuf), "Cache volume %d specified at line %d is not defined in volume.config", volume_num,
1249+
cln + 1);
12311250
errStr = errStrBuf;
12321251
goto MAP_ERROR;
12331252
}

0 commit comments

Comments
 (0)