On 02/03/2013 10:06 PM, Alex Rousskov wrote:
> On 02/03/2013 08:31 PM, Amos Jeffries wrote:
>>> On 2/3/2013 8:29 PM, Alex Rousskov wrote:
>>>> To be consistent with ufs, we should probably change rock behavior from
>>>> initializing the database to doing nothing if the configured database
>>>> directory already exists. Like ufs, rock will rely on directory
>>>> existence for that test (regardless of what may be inside that
>>>> configured directory). In other words, squid-z is not "validate and
>>>> initialize" but "initialize if the configured directory is not there".
>>>>
>>>> Any objections to that rock change?
>> Absolutely none. Start by making both perform an existence check before
>> doing *anything*.
>> * initialize if it does not exist yet
> Will do.
The attached trunk patch makes squid -z for cache_dir rock work like UFS
instead of like COSS.
When a startup script runs squid -z by mistake against a cache_dir that
is already initialized and full of cached entries, some admins prefer
that nothing happens. Rock store now skips reinitialization if both the
cache_dir directory and the db file in that directory exist. If one or
both are missing, the missing pieces are created.
UFS does something similar because it creates missing L1 and L2
directories but does not erase any entries already present in the
cache_dir path. COSS, OTOH, re-initializes the existing db (but nobody
noticed or complained loud enough, apparently). Rock behavior will now
be closer to UFS.
To clean a corrupted cache_dir, the admin must remove it before running
squid-z.
Thank you,
Alex.
Make squid -z for cache_dir rock work like UFS instead of like COSS.
When a startup script runs squid -z by mistake against a cache_dir that is
already initialized and full of cached entries, some admins prefer that
nothing happens. Rock store now skips reinitialization if both the cache_dir
directory and the db file in that directory exist. If one or both are missing,
the missing pieces are created.
UFS does something similar because it creates missing L1 and L2 directories
but does not erase any entries already present in the cache_dir path. COSS,
OTOH, re-initializes the existing db (but nobody noticed or complained loud
enough, apparently). Rock behavior will now be closer to UFS.
To clean a corrupted cache_dir, the admin must remove it before running squid-z.
=== modified file 'src/fs/rock/RockSwapDir.cc'
--- src/fs/rock/RockSwapDir.cc 2013-01-21 07:15:09 +0000
+++ src/fs/rock/RockSwapDir.cc 2013-02-04 19:36:56 +0000
@@ -143,51 +143,63 @@
{
const int64_t eLimitLo = map ? map->entryLimit() : 0; // dynamic shrinking unsupported
const int64_t eWanted = (maxSize() - HeaderSize)/maxObjectSize();
return min(max(eLimitLo, eWanted), entryLimitHigh());
}
// TODO: encapsulate as a tool; identical to CossSwapDir::create()
void
Rock::SwapDir::create()
{
assert(path);
assert(filePath);
if (UsingSmp() && !IamDiskProcess()) {
debugs (47,3, HERE << "disker will create in " << path);
return;
}
debugs (47,3, HERE << "creating in " << path);
- struct stat swap_sb;
- if (::stat(path, &swap_sb) < 0) {
+ struct stat dir_sb;
+ if (::stat(path, &dir_sb) == 0) {
+ struct stat file_sb;
+ if (::stat(filePath, &file_sb) == 0) {
+ debugs (47, DBG_IMPORTANT, "Skipping existing Rock db: " << filePath);
+ return;
+ }
+ // else the db file is not there or is not accessible, and we will try
+ // to create it later below, generating a detailed error on failures.
+ } else { // path does not exist or is inaccessible
+ // If path exists but is not accessible, mkdir() below will fail, and
+ // the admin should see the error and act accordingly, so there is
+ // no need to distinguish ENOENT from other possible stat() errors.
debugs (47, DBG_IMPORTANT, "Creating Rock db directory: " << path);
const int res = mkdir(path, 0700);
if (res != 0) {
debugs(47, DBG_CRITICAL, "Failed to create Rock db dir " << path <<
": " << xstrerror());
fatal("Rock Store db creation error");
}
}
+ debugs (47, DBG_IMPORTANT, "Creating Rock db: " << filePath);
#if SLOWLY_FILL_WITH_ZEROS
char block[1024];
Must(maxSize() % sizeof(block) == 0);
memset(block, '\0', sizeof(block));
const int swap = open(filePath, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600);
for (off_t offset = 0; offset < maxSize(); offset += sizeof(block)) {
if (write(swap, block, sizeof(block)) != sizeof(block)) {
debugs(47, DBG_CRITICAL, "ERROR: Failed to create Rock Store db in " << filePath <<
": " << xstrerror());
fatal("Rock Store db creation error");
}
}
close(swap);
#else
const int swap = open(filePath, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0600);
if (swap < 0) {
debugs(47, DBG_CRITICAL, "ERROR: Failed to initialize Rock Store db in " << filePath <<
"; create error: " << xstrerror());
fatal("Rock Store db creation error");