currentIOOptions(new ConfigOptionVector()),
ioType(xstrdup(anIOType)),
cur_size(0),
- n_disk_objects(0)
+ n_disk_objects(0),
+ rebuilding_(false)
{
/* modulename is only set to disk modules that are built, by configure,
* so the Find call should never return NULL here.
void
Fs::Ufs::UFSSwapDir::openLog()
{
+ assert(NumberOfUFSDirs || !UFSDirToGlobalDirMapping);
+ ++NumberOfUFSDirs;
+ assert(NumberOfUFSDirs <= Config.cacheSwap.n_configured);
+
+ if (rebuilding_) { // we did not close the temporary log used for rebuilding
+ assert(swaplog_fd >= 0);
+ return;
+ }
+
char *logPath;
logPath = logFile();
swaplog_fd = file_open(logPath, O_WRONLY | O_CREAT | O_BINARY);
}
debugs(50, 3, HERE << "Cache Dir #" << index << " log opened on FD " << swaplog_fd);
-
- if (0 == NumberOfUFSDirs)
- assert(NULL == UFSDirToGlobalDirMapping);
-
- ++NumberOfUFSDirs;
-
- assert(NumberOfUFSDirs <= Config.cacheSwap.n_configured);
}
void
if (swaplog_fd < 0) /* not open */
return;
+ --NumberOfUFSDirs;
+ assert(NumberOfUFSDirs >= 0);
+ if (!NumberOfUFSDirs)
+ safe_free(UFSDirToGlobalDirMapping);
+
+ if (rebuilding_) // we cannot close the temporary log used for rebuilding
+ return;
+
file_close(swaplog_fd);
debugs(47, 3, "Cache Dir #" << index << " log closed on FD " << swaplog_fd);
swaplog_fd = -1;
-
- --NumberOfUFSDirs;
-
- assert(NumberOfUFSDirs >= 0);
-
- if (0 == NumberOfUFSDirs)
- safe_free(UFSDirToGlobalDirMapping);
}
bool
void
Fs::Ufs::UFSSwapDir::closeTmpSwapLog()
{
+ assert(rebuilding_);
+ rebuilding_ = false;
+
char *swaplog_path = xstrdup(logFile(NULL)); // where the swaplog should be
char *tmp_path = xstrdup(logFile(".new")); // the temporary file we have generated
int fd;
FILE *
Fs::Ufs::UFSSwapDir::openTmpSwapLog(int *clean_flag, int *zero_flag)
{
+ assert(!rebuilding_);
+
char *swaplog_path = xstrdup(logFile(NULL));
char *clean_path = xstrdup(logFile(".last-clean"));
char *new_path = xstrdup(logFile(".new"));
}
swaplog_fd = fd;
+ rebuilding_ = true;
{
const StoreSwapLogHeader header;
cleanLog = NULL;
}
-void
-Fs::Ufs::UFSSwapDir::CleanEvent(void *)
+/// safely cleans a few unused files if possible
+int
+Fs::Ufs::UFSSwapDir::HandleCleanEvent()
{
static int swap_index = 0;
int i;
int j = 0;
int n = 0;
- /*
- * Assert that there are UFS cache_dirs configured, otherwise
- * we should never be called.
- */
- assert(NumberOfUFSDirs);
+
+ if (!NumberOfUFSDirs)
+ return 0; // probably in the middle of reconfiguration
if (NULL == UFSDirToGlobalDirMapping) {
SwapDir *sd;
++swap_index;
}
+ return n;
+}
+
+void
+Fs::Ufs::UFSSwapDir::CleanEvent(void *)
+{
+ const int n = HandleCleanEvent();
eventAdd("storeDirClean", CleanEvent, NULL,
15.0 * exp(-0.25 * n), 1);
}
void
Fs::Ufs::UFSSwapDir::logEntry(const StoreEntry & e, int op) const
{
+ if (swaplog_fd < 0) {
+ debugs(36, 5, "cannot log " << e << " in the middle of reconfiguration");
+ return;
+ }
+
StoreSwapLogData *s = new StoreSwapLogData;
s->op = (char) op;
s->swap_filen = e.swap_filen;
// Check for store_dirs_rebuilding because fatal() often calls us in early
// initialization phases, before store log is initialized and ready. Also,
- // some stores probably do not support log cleanup during Store rebuilding.
+ // some stores do not support log cleanup during Store rebuilding.
if (StoreController::store_dirs_rebuilding) {
debugs(20, DBG_IMPORTANT, "Not currently OK to rewrite swap log.");
debugs(20, DBG_IMPORTANT, "storeDirWriteCleanLogs: Operation aborted.");