You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ma...@apache.org on 2019/11/29 09:14:26 UTC
[cassandra] branch cassandra-3.0 updated: Fix various data
directory prefix matching issues
This is an automated email from the ASF dual-hosted git repository.
marcuse pushed a commit to branch cassandra-3.0
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/cassandra-3.0 by this push:
new eda5db2 Fix various data directory prefix matching issues
eda5db2 is described below
commit eda5db28e38c8652014cadd15ee49a8b8faacf21
Author: Marcus Eriksson <ma...@apache.org>
AuthorDate: Mon Sep 30 14:33:33 2019 +0200
Fix various data directory prefix matching issues
Patch by marcuse; reviewed by Sam Tunnicliffe for CASSANDRA-13974
---
CHANGES.txt | 1 +
src/java/org/apache/cassandra/db/Directories.java | 8 +++-
.../org/apache/cassandra/io/util/FileUtils.java | 4 +-
.../org/apache/cassandra/db/DirectoriesTest.java | 43 ++++++++++++++++++++++
.../apache/cassandra/io/util/FileUtilsTest.java | 10 +++++
5 files changed, 63 insertions(+), 3 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index 6dd6d0a..cdebc03 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
3.0.20
+ * Fix various data directory prefix matching issues (CASSANDRA-13974)
* Minimize clustering values in metadata collector (CASSANDRA-15400)
* Avoid over-trimming of results in mixed mode clusters (CASSANDRA-15405)
* validate value sizes in LegacyLayout (CASSANDRA-15373)
diff --git a/src/java/org/apache/cassandra/db/Directories.java b/src/java/org/apache/cassandra/db/Directories.java
index ae7700c..b104509 100644
--- a/src/java/org/apache/cassandra/db/Directories.java
+++ b/src/java/org/apache/cassandra/db/Directories.java
@@ -26,6 +26,7 @@ import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
@@ -287,8 +288,13 @@ public class Directories
{
if (dataDirectory != null)
for (File dir : dataPaths)
- if (dir.getAbsolutePath().startsWith(dataDirectory.location.getAbsolutePath()))
+ {
+ // Note that we must compare absolute paths (not canonical) here since keyspace directories might be symlinks
+ Path dirPath = Paths.get(dir.getAbsolutePath());
+ Path locationPath = Paths.get(dataDirectory.location.getAbsolutePath());
+ if (dirPath.startsWith(locationPath))
return dir;
+ }
return null;
}
diff --git a/src/java/org/apache/cassandra/io/util/FileUtils.java b/src/java/org/apache/cassandra/io/util/FileUtils.java
index 54efd27..f9406e5 100644
--- a/src/java/org/apache/cassandra/io/util/FileUtils.java
+++ b/src/java/org/apache/cassandra/io/util/FileUtils.java
@@ -318,8 +318,8 @@ public final class FileUtils
/** Return true if file is contained in folder */
public static boolean isContained(File folder, File file)
{
- String folderPath = getCanonicalPath(folder);
- String filePath = getCanonicalPath(file);
+ Path folderPath = Paths.get(getCanonicalPath(folder));
+ Path filePath = Paths.get(getCanonicalPath(file));
return filePath.startsWith(folderPath);
}
diff --git a/test/unit/org/apache/cassandra/db/DirectoriesTest.java b/test/unit/org/apache/cassandra/db/DirectoriesTest.java
index 7c4ff7a..e4268f6 100644
--- a/test/unit/org/apache/cassandra/db/DirectoriesTest.java
+++ b/test/unit/org/apache/cassandra/db/DirectoriesTest.java
@@ -20,6 +20,9 @@ package org.apache.cassandra.db;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
@@ -467,6 +470,46 @@ public class DirectoriesTest
}
}
+ @Test
+ public void testGetLocationForDisk()
+ {
+ DataDirectory [] paths = new DataDirectory[3];
+ paths[0] = new DataDirectory(new File("/tmp/aaa"));
+ paths[1] = new DataDirectory(new File("/tmp/aa"));
+ paths[2] = new DataDirectory(new File("/tmp/a"));
+
+ for (CFMetaData cfm : CFM)
+ {
+ Directories dirs = new Directories(cfm, paths);
+ for (DataDirectory dir : paths)
+ {
+ String p = dirs.getLocationForDisk(dir).getAbsolutePath() + File.separator;
+ assertTrue(p.startsWith(dir.location.getAbsolutePath() + File.separator));
+ }
+ }
+ }
+
+ @Test
+ public void testGetLocationWithSymlinks() throws IOException
+ {
+ Path p = Files.createTempDirectory("something");
+ Path symlinktarget = Files.createDirectories(p.resolve("symlinktarget"));
+ Path ddir = Files.createDirectories(p.resolve("datadir1"));
+
+ Path p1 = Files.createDirectories(ddir.resolve("p1").resolve("ks")).getParent(); // the data dir does not include the keyspace dir
+ Path p2 = Files.createDirectories(ddir.resolve("p2"));
+ Path l1 = Files.createSymbolicLink(p2.resolve("ks"), symlinktarget);
+
+ DataDirectory path1 = new DataDirectory(p1.toFile());
+ DataDirectory path2 = new DataDirectory(p2.toFile());
+ Directories dirs = new Directories(CFM.iterator().next(), new DataDirectory[] {path1, path2});
+ dirs.getLocationForDisk(new DataDirectory(p1.toFile()));
+ dirs.getLocationForDisk(new DataDirectory(p2.toFile()));
+
+ assertTrue(dirs.getLocationForDisk(path2).toPath().startsWith(l1));
+ assertTrue(dirs.getLocationForDisk(path1).toPath().startsWith(p1));
+ }
+
private List<Directories.DataDirectoryCandidate> getWriteableDirectories(DataDirectory[] dataDirectories, long writeSize)
{
// copied from Directories.getWriteableLocation(long)
diff --git a/test/unit/org/apache/cassandra/io/util/FileUtilsTest.java b/test/unit/org/apache/cassandra/io/util/FileUtilsTest.java
index 7110504..8d1b752 100644
--- a/test/unit/org/apache/cassandra/io/util/FileUtilsTest.java
+++ b/test/unit/org/apache/cassandra/io/util/FileUtilsTest.java
@@ -26,6 +26,7 @@ import java.nio.file.Files;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class FileUtilsTest
@@ -52,4 +53,13 @@ public class FileUtilsTest
assertEquals(0, b.length);
}
+ @Test
+ public void testIsContained()
+ {
+ assertTrue(FileUtils.isContained(new File("/tmp/abc"), new File("/tmp/abc")));
+ assertFalse(FileUtils.isContained(new File("/tmp/abc"), new File("/tmp/abcd")));
+ assertTrue(FileUtils.isContained(new File("/tmp/abc"), new File("/tmp/abc/d")));
+ assertTrue(FileUtils.isContained(new File("/tmp/abc/../abc"), new File("/tmp/abc/d")));
+ assertFalse(FileUtils.isContained(new File("/tmp/abc/../abc"), new File("/tmp/abcc")));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org