HDFS-10225. DataNode hot swap drives should disallow storage type changes. Contributed by Lei (Eddy) Xu.
(cherry picked from commit 132deb4cac
)
This commit is contained in:
parent
c96cb3fd48
commit
8559442ed1
|
@ -625,7 +625,7 @@ public class DataNode extends ReconfigurableBase
|
||||||
* @param newVolumes a comma separated string that specifies the data volumes.
|
* @param newVolumes a comma separated string that specifies the data volumes.
|
||||||
* @return changed volumes.
|
* @return changed volumes.
|
||||||
* @throws IOException if none of the directories are specified in the
|
* @throws IOException if none of the directories are specified in the
|
||||||
* configuration.
|
* configuration, or the storage type of a directory is changed.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
ChangedVolumes parseChangedVolumes(String newVolumes) throws IOException {
|
ChangedVolumes parseChangedVolumes(String newVolumes) throws IOException {
|
||||||
|
@ -637,6 +637,12 @@ public class DataNode extends ReconfigurableBase
|
||||||
throw new IOException("No directory is specified.");
|
throw new IOException("No directory is specified.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use the existing StorageLocation to detect storage type changes.
|
||||||
|
Map<String, StorageLocation> existingLocations = new HashMap<>();
|
||||||
|
for (StorageLocation loc : getStorageLocations(this.conf)) {
|
||||||
|
existingLocations.put(loc.getFile().getCanonicalPath(), loc);
|
||||||
|
}
|
||||||
|
|
||||||
ChangedVolumes results = new ChangedVolumes();
|
ChangedVolumes results = new ChangedVolumes();
|
||||||
results.newLocations.addAll(locations);
|
results.newLocations.addAll(locations);
|
||||||
|
|
||||||
|
@ -650,6 +656,12 @@ public class DataNode extends ReconfigurableBase
|
||||||
if (location.getFile().getCanonicalPath().equals(
|
if (location.getFile().getCanonicalPath().equals(
|
||||||
dir.getRoot().getCanonicalPath())) {
|
dir.getRoot().getCanonicalPath())) {
|
||||||
sl.remove();
|
sl.remove();
|
||||||
|
StorageLocation old = existingLocations.get(
|
||||||
|
location.getFile().getCanonicalPath());
|
||||||
|
if (old != null &&
|
||||||
|
old.getStorageType() != location.getStorageType()) {
|
||||||
|
throw new IOException("Changing storage type is not allowed.");
|
||||||
|
}
|
||||||
results.unchangedLocations.add(location);
|
results.unchangedLocations.add(location);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.apache.hadoop.fs.FSDataOutputStream;
|
||||||
import org.apache.hadoop.fs.FileStatus;
|
import org.apache.hadoop.fs.FileStatus;
|
||||||
import org.apache.hadoop.fs.FileSystem;
|
import org.apache.hadoop.fs.FileSystem;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
|
import org.apache.hadoop.fs.StorageType;
|
||||||
import org.apache.hadoop.hdfs.BlockMissingException;
|
import org.apache.hadoop.hdfs.BlockMissingException;
|
||||||
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
||||||
import org.apache.hadoop.hdfs.DFSTestUtil;
|
import org.apache.hadoop.hdfs.DFSTestUtil;
|
||||||
|
@ -255,6 +256,27 @@ public class TestDataNodeHotSwapVolumes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseStorageTypeChanges() throws IOException {
|
||||||
|
startDFSCluster(1, 1);
|
||||||
|
DataNode dn = cluster.getDataNodes().get(0);
|
||||||
|
Configuration conf = dn.getConf();
|
||||||
|
List<StorageLocation> oldLocations = DataNode.getStorageLocations(conf);
|
||||||
|
|
||||||
|
// Change storage type of an existing StorageLocation
|
||||||
|
String newLoc = String.format("[%s]%s", StorageType.SSD,
|
||||||
|
oldLocations.get(1).getUri());
|
||||||
|
String newDataDirs = oldLocations.get(0).toString() + "," + newLoc;
|
||||||
|
|
||||||
|
try {
|
||||||
|
dn.parseChangedVolumes(newDataDirs);
|
||||||
|
fail("should throw IOE because storage type changes.");
|
||||||
|
} catch (IOException e) {
|
||||||
|
GenericTestUtils.assertExceptionContains(
|
||||||
|
"Changing storage type is not allowed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Add volumes to the first DataNode. */
|
/** Add volumes to the first DataNode. */
|
||||||
private void addVolumes(int numNewVolumes)
|
private void addVolumes(int numNewVolumes)
|
||||||
throws ReconfigurationException, IOException {
|
throws ReconfigurationException, IOException {
|
||||||
|
|
Loading…
Reference in New Issue