Skip to content

Commit

Permalink
Fix race condition in MakeDirs
Browse files Browse the repository at this point in the history
If there are 2 concurrent processes creating the same directories, then it will fail

I noticed this on the CI errors of bazelbuild#567, and a co-worker was hitting it
today. I suspect invalidating the worker or other updates triggered big
rebuilds.

I don't know of a perfect repro but, at a 10% rate: invoking Bazel to
build 2 swift libraries in the same BUILD file.
  • Loading branch information
jerrymarino committed Jun 10, 2021
1 parent 914eff9 commit 64dbf25
Showing 1 changed file with 26 additions and 2 deletions.
28 changes: 26 additions & 2 deletions tools/common/file_system.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <sys/types.h>
#include <unistd.h>

#include <iostream>
#include <string>

#ifdef __APPLE__
Expand Down Expand Up @@ -99,7 +100,13 @@ bool MakeDirs(const std::string &path, int mode) {
struct stat dir_stats;
if (stat(path.c_str(), &dir_stats) == 0) {
// Return true if the directory already exists.
return S_ISDIR(dir_stats.st_mode);
if (!S_ISDIR(dir_stats.st_mode)) {
std::cerr << "error: path exists and isn't a directory (" << path.c_str()
<< ") \n";
return false;
} else {
return true;
}
}

// Recurse to create the parent directory.
Expand All @@ -108,5 +115,22 @@ bool MakeDirs(const std::string &path, int mode) {
}

// Create the directory that was requested.
return mkdir(path.c_str(), mode) == 0;
int mkdir_ret = mkdir(path.c_str(), mode);
if (mkdir_ret == 0) {
return true;
} else if (mkdir_ret == EEXIST) {
int chmod_ret = chmod(path.c_str(), S_IRWXU);
if (chmod_ret == 0) {
return true;
}
std::cerr << "error:" << strerror(errno) << ":" << path.c_str() << "\n";
return false;
}

// If we can access the directory assume it's valid
if (access(path.c_str(), F_OK) == 0) {
return true;
}
std::cerr << "error:" << strerror(errno) << ":" << path.c_str() << "\n";
return false;
}

0 comments on commit 64dbf25

Please sign in to comment.