in mcrouter/AsyncLog.cpp [60:209]
bool AsyncLog::openFile() {
char path[PATH_MAX + 1];
time_t now = time(nullptr);
pid_t tid = syscall(SYS_gettid);
struct tm date;
struct stat st;
if (file_ && now - spoolTime_ <= DEFAULT_ASYNCLOG_LIFETIME) {
return true;
}
if (file_) {
file_.reset();
}
localtime_r(&now, &date);
char hour_path[PATH_MAX + 1];
time_t hour_time = now - (now % 3600);
if (snprintf(
hour_path,
PATH_MAX,
"%s/%04d%02d%02dT%02d-%lld",
options_.async_spool.c_str(),
date.tm_year + 1900,
date.tm_mon + 1,
date.tm_mday,
date.tm_hour,
(long long)hour_time) > PATH_MAX) {
hour_path[PATH_MAX] = '\0';
MC_LOG_FAILURE(
options_,
failure::Category::kSystemError,
"async log hourly spool path is too long: {}",
hour_path);
return false;
}
if (stat(hour_path, &st) != 0) {
mode_t old_umask = umask(0);
int ret = mkdir(hour_path, 0777);
int mkdir_errno = 0;
if (ret != 0) {
mkdir_errno = errno;
}
if (old_umask != 0) {
umask(old_umask);
}
/* EEXIST is possible due to a race. We don't care. */
if (ret != 0 && mkdir_errno != EEXIST) {
MC_LOG_FAILURE(
options_,
failure::Category::kSystemError,
"couldn't create async log hour spool path: {}. Reason: {}",
hour_path,
folly::errnoStr(mkdir_errno));
return false;
}
}
if (snprintf(
path,
PATH_MAX,
"%s/%04d%02d%02dT%02d%02d%02d-%lld-%s-%s-t%d-%p",
hour_path,
date.tm_year + 1900,
date.tm_mon + 1,
date.tm_mday,
date.tm_hour,
date.tm_min,
date.tm_sec,
(long long)now,
options_.service_name.c_str(),
options_.router_name.c_str(),
tid,
this) > PATH_MAX) {
path[PATH_MAX] = '\0';
MC_LOG_FAILURE(
options_,
failure::Category::kSystemError,
"async log path is too long: {}",
path);
return false;
}
int fd = -1;
/*
* Just in case, append to the log if it exists
*/
if (stat(path, &st) != 0) {
fd = open(path, O_WRONLY | O_CREAT, 0666);
if (fd < 0) {
MC_LOG_FAILURE(
options_,
failure::Category::kSystemError,
"Can't create and open async store {}: {}",
path,
folly::errnoStr(errno));
return false;
}
} else {
fd = open(path, O_WRONLY | O_APPEND, 0666);
if (fd < 0) {
MC_LOG_FAILURE(
options_,
failure::Category::kSystemError,
"Can't re-open async store {}: {}",
path,
folly::errnoStr(errno));
return false;
}
}
if (fstat(fd, &st)) {
MC_LOG_FAILURE(
options_,
failure::Category::kSystemError,
"Can't stat async store {}: {}",
path,
folly::errnoStr(errno));
closeFd(fd);
return false;
}
if (!S_ISREG(st.st_mode)) {
MC_LOG_FAILURE(
options_,
failure::Category::kSystemError,
"Async store exists but is not a file: {}: {}",
path,
folly::errnoStr(errno));
closeFd(fd);
return false;
}
file_ = createFile(fd);
if (!file_) {
MC_LOG_FAILURE(
options_,
failure::Category::kSystemError,
"Unable to allocate memory for file_: {}",
folly::errnoStr(errno));
closeFd(fd);
return false;
}
spoolTime_ = now;
VLOG(1) << "Opened async store for " << path;
return true;
}