diff --git a/HISTORY.md b/HISTORY.md index a406fea4a..154ee23f1 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ # Rocksdb Change Log ## Unreleased ### Bug Fixes +* Fixed bug which caused rocksdb failure in the situation when rocksdb was accessible using UNC path * Fixed a race condition when 2PC is disabled and WAL tracking in the MANIFEST is enabled. The race condition is between two background flush threads trying to install flush results, causing a WAL deletion not tracked in the MANIFEST. A future DB open may fail. * Fixed a heap use-after-free race with DropColumnFamily. * Fixed a bug that `rocksdb.read.block.compaction.micros` cannot track compaction stats (#9722). diff --git a/db/filename_test.cc b/db/filename_test.cc index d166876ba..23f6974b1 100644 --- a/db/filename_test.cc +++ b/db/filename_test.cc @@ -171,6 +171,69 @@ TEST_F(FileNameTest, Construction) { ASSERT_EQ(kMetaDatabase, type); } +TEST_F(FileNameTest, NormalizePath) { + // No leading slash + const std::string sep = std::string(1, kFilePathSeparator); + + std::string expected = "FOLDER" + sep + "filename.ext"; + std::string given = "FOLDER" + sep + "filename.ext"; + + ASSERT_EQ(expected, NormalizePath(given)); + + // Two chars /a + + expected = sep + "a"; + given = expected; + ASSERT_EQ(expected, NormalizePath(given)); + + // Two chars a/ + expected = "a" + sep; + given = expected; + ASSERT_EQ(expected, NormalizePath(given)); + + // Server only + expected = sep + sep + "a"; + given = expected; + ASSERT_EQ(expected, NormalizePath(given)); + + // Two slashes after character + expected = "a" + sep; + given = "a" + sep + sep; + + ASSERT_EQ(expected, NormalizePath(given)); + + // slash only / + expected = sep; + given = expected; + ASSERT_EQ(expected, NormalizePath(given)); + + // UNC only // + expected = sep; + given = sep + sep; + + ASSERT_EQ(expected, NormalizePath(given)); + + // 3 slashesy // + expected = sep + sep; + given = sep + sep + sep; + ASSERT_EQ(expected, NormalizePath(given)); + + // 3 slashes // + expected = sep + sep + "a" + sep; + given = sep + sep + sep + "a" + sep; + ASSERT_EQ(expected, NormalizePath(given)); + + // 2 separators in the middle + expected = "a" + sep + "b"; + given = "a" + sep + sep + "b"; + ASSERT_EQ(expected, NormalizePath(given)); + + // UNC with duplicate slashes + expected = sep + sep + "SERVER" + sep + "a" + sep + "b" + sep + "c"; + given = sep + sep + "SERVER" + sep + "a" + sep + sep + "b" + sep + "c"; + ASSERT_EQ(expected, NormalizePath(given)); +} + } // namespace ROCKSDB_NAMESPACE int main(int argc, char** argv) { diff --git a/file/filename.cc b/file/filename.cc index 358f88cf0..f63a469dd 100644 --- a/file/filename.cc +++ b/file/filename.cc @@ -491,6 +491,12 @@ Status GetInfoLogFiles(const std::shared_ptr& fs, std::string NormalizePath(const std::string& path) { std::string dst; + + if (path.length() > 2 && path[0] == kFilePathSeparator && + path[1] == kFilePathSeparator) { // Handle UNC names + dst.append(2, kFilePathSeparator); + } + for (auto c : path) { if (!dst.empty() && (c == kFilePathSeparator || c == '/') && (dst.back() == kFilePathSeparator || dst.back() == '/')) {