|
@@ -272,7 +272,7 @@ public class DataNode extends Configured
|
|
private JvmPauseMonitor pauseMonitor;
|
|
private JvmPauseMonitor pauseMonitor;
|
|
|
|
|
|
private SecureResources secureResources = null;
|
|
private SecureResources secureResources = null;
|
|
- private AbstractList<File> dataDirs;
|
|
|
|
|
|
+ private AbstractList<StorageLocation> dataDirs;
|
|
private Configuration conf;
|
|
private Configuration conf;
|
|
|
|
|
|
private final List<String> usersWithLocalPathAccess;
|
|
private final List<String> usersWithLocalPathAccess;
|
|
@@ -280,21 +280,12 @@ public class DataNode extends Configured
|
|
ReadaheadPool readaheadPool;
|
|
ReadaheadPool readaheadPool;
|
|
private final boolean getHdfsBlockLocationsEnabled;
|
|
private final boolean getHdfsBlockLocationsEnabled;
|
|
|
|
|
|
- /**
|
|
|
|
- * Create the DataNode given a configuration and an array of dataDirs.
|
|
|
|
- * 'dataDirs' is where the blocks are stored.
|
|
|
|
- */
|
|
|
|
- DataNode(final Configuration conf,
|
|
|
|
- final AbstractList<File> dataDirs) throws IOException {
|
|
|
|
- this(conf, dataDirs, null);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Create the DataNode given a configuration, an array of dataDirs,
|
|
* Create the DataNode given a configuration, an array of dataDirs,
|
|
* and a namenode proxy
|
|
* and a namenode proxy
|
|
*/
|
|
*/
|
|
- DataNode(final Configuration conf,
|
|
|
|
- final AbstractList<File> dataDirs,
|
|
|
|
|
|
+ DataNode(final Configuration conf,
|
|
|
|
+ final AbstractList<StorageLocation> dataDirs,
|
|
final SecureResources resources) throws IOException {
|
|
final SecureResources resources) throws IOException {
|
|
super(conf);
|
|
super(conf);
|
|
|
|
|
|
@@ -711,7 +702,7 @@ public class DataNode extends Configured
|
|
* @throws IOException
|
|
* @throws IOException
|
|
*/
|
|
*/
|
|
void startDataNode(Configuration conf,
|
|
void startDataNode(Configuration conf,
|
|
- AbstractList<File> dataDirs,
|
|
|
|
|
|
+ AbstractList<StorageLocation> dataDirs,
|
|
// DatanodeProtocol namenode,
|
|
// DatanodeProtocol namenode,
|
|
SecureResources resources
|
|
SecureResources resources
|
|
) throws IOException {
|
|
) throws IOException {
|
|
@@ -861,7 +852,7 @@ public class DataNode extends Configured
|
|
* If this is the first block pool to register, this also initializes
|
|
* If this is the first block pool to register, this also initializes
|
|
* the datanode-scoped storage.
|
|
* the datanode-scoped storage.
|
|
*
|
|
*
|
|
- * @param nsInfo the handshake response from the NN.
|
|
|
|
|
|
+ * @param bpos block pool to initialize and register with the NameNode.
|
|
* @throws IOException if the NN is inconsistent with the local storage.
|
|
* @throws IOException if the NN is inconsistent with the local storage.
|
|
*/
|
|
*/
|
|
void initBlockPool(BPOfferService bpos) throws IOException {
|
|
void initBlockPool(BPOfferService bpos) throws IOException {
|
|
@@ -1688,17 +1679,39 @@ public class DataNode extends Configured
|
|
printUsage(System.err);
|
|
printUsage(System.err);
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
- Collection<URI> dataDirs = getStorageDirs(conf);
|
|
|
|
|
|
+ Collection<StorageLocation> dataLocations = getStorageLocations(conf);
|
|
UserGroupInformation.setConfiguration(conf);
|
|
UserGroupInformation.setConfiguration(conf);
|
|
SecurityUtil.login(conf, DFS_DATANODE_KEYTAB_FILE_KEY,
|
|
SecurityUtil.login(conf, DFS_DATANODE_KEYTAB_FILE_KEY,
|
|
DFS_DATANODE_USER_NAME_KEY);
|
|
DFS_DATANODE_USER_NAME_KEY);
|
|
- return makeInstance(dataDirs, conf, resources);
|
|
|
|
|
|
+ return makeInstance(dataLocations, conf, resources);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static Collection<StorageLocation> parseStorageLocations(
|
|
|
|
+ Collection<String> rawLocations) {
|
|
|
|
+ List<StorageLocation> locations =
|
|
|
|
+ new ArrayList<StorageLocation>(rawLocations.size());
|
|
|
|
+
|
|
|
|
+ for(String locationString : rawLocations) {
|
|
|
|
+ StorageLocation location;
|
|
|
|
+ try {
|
|
|
|
+ location = StorageLocation.parse(locationString);
|
|
|
|
+ } catch (IOException ioe) {
|
|
|
|
+ LOG.error("Failed to parse storage location " + locationString);
|
|
|
|
+ continue;
|
|
|
|
+ } catch (IllegalArgumentException iae) {
|
|
|
|
+ LOG.error(iae.toString());
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ locations.add(location);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return locations;
|
|
}
|
|
}
|
|
|
|
|
|
- static Collection<URI> getStorageDirs(Configuration conf) {
|
|
|
|
- Collection<String> dirNames =
|
|
|
|
- conf.getTrimmedStringCollection(DFS_DATANODE_DATA_DIR_KEY);
|
|
|
|
- return Util.stringCollectionAsURIs(dirNames);
|
|
|
|
|
|
+ static Collection<StorageLocation> getStorageLocations(Configuration conf) {
|
|
|
|
+ return parseStorageLocations(
|
|
|
|
+ conf.getTrimmedStringCollection(DFS_DATANODE_DATA_DIR_KEY));
|
|
}
|
|
}
|
|
|
|
|
|
/** Instantiate & Start a single datanode daemon and wait for it to finish.
|
|
/** Instantiate & Start a single datanode daemon and wait for it to finish.
|
|
@@ -1764,51 +1777,45 @@ public class DataNode extends Configured
|
|
* no directory from this directory list can be created.
|
|
* no directory from this directory list can be created.
|
|
* @throws IOException
|
|
* @throws IOException
|
|
*/
|
|
*/
|
|
- static DataNode makeInstance(Collection<URI> dataDirs, Configuration conf,
|
|
|
|
- SecureResources resources) throws IOException {
|
|
|
|
|
|
+ static DataNode makeInstance(Collection<StorageLocation> dataDirs,
|
|
|
|
+ Configuration conf, SecureResources resources) throws IOException {
|
|
LocalFileSystem localFS = FileSystem.getLocal(conf);
|
|
LocalFileSystem localFS = FileSystem.getLocal(conf);
|
|
FsPermission permission = new FsPermission(
|
|
FsPermission permission = new FsPermission(
|
|
conf.get(DFS_DATANODE_DATA_DIR_PERMISSION_KEY,
|
|
conf.get(DFS_DATANODE_DATA_DIR_PERMISSION_KEY,
|
|
DFS_DATANODE_DATA_DIR_PERMISSION_DEFAULT));
|
|
DFS_DATANODE_DATA_DIR_PERMISSION_DEFAULT));
|
|
DataNodeDiskChecker dataNodeDiskChecker =
|
|
DataNodeDiskChecker dataNodeDiskChecker =
|
|
new DataNodeDiskChecker(permission);
|
|
new DataNodeDiskChecker(permission);
|
|
- ArrayList<File> dirs =
|
|
|
|
- getDataDirsFromURIs(dataDirs, localFS, dataNodeDiskChecker);
|
|
|
|
|
|
+ ArrayList<StorageLocation> locations =
|
|
|
|
+ checkStorageLocations(dataDirs, localFS, dataNodeDiskChecker);
|
|
DefaultMetricsSystem.initialize("DataNode");
|
|
DefaultMetricsSystem.initialize("DataNode");
|
|
|
|
|
|
- assert dirs.size() > 0 : "number of data directories should be > 0";
|
|
|
|
- return new DataNode(conf, dirs, resources);
|
|
|
|
|
|
+ assert locations.size() > 0 : "number of data directories should be > 0";
|
|
|
|
+ return new DataNode(conf, locations, resources);
|
|
}
|
|
}
|
|
|
|
|
|
// DataNode ctor expects AbstractList instead of List or Collection...
|
|
// DataNode ctor expects AbstractList instead of List or Collection...
|
|
- static ArrayList<File> getDataDirsFromURIs(Collection<URI> dataDirs,
|
|
|
|
|
|
+ static ArrayList<StorageLocation> checkStorageLocations(
|
|
|
|
+ Collection<StorageLocation> dataDirs,
|
|
LocalFileSystem localFS, DataNodeDiskChecker dataNodeDiskChecker)
|
|
LocalFileSystem localFS, DataNodeDiskChecker dataNodeDiskChecker)
|
|
throws IOException {
|
|
throws IOException {
|
|
- ArrayList<File> dirs = new ArrayList<File>();
|
|
|
|
|
|
+ ArrayList<StorageLocation> locations = new ArrayList<StorageLocation>();
|
|
StringBuilder invalidDirs = new StringBuilder();
|
|
StringBuilder invalidDirs = new StringBuilder();
|
|
- for (URI dirURI : dataDirs) {
|
|
|
|
- if (!"file".equalsIgnoreCase(dirURI.getScheme())) {
|
|
|
|
- LOG.warn("Unsupported URI schema in " + dirURI + ". Ignoring ...");
|
|
|
|
- invalidDirs.append("\"").append(dirURI).append("\" ");
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- // drop any (illegal) authority in the URI for backwards compatibility
|
|
|
|
- File dir = new File(dirURI.getPath());
|
|
|
|
|
|
+ for (StorageLocation location : dataDirs) {
|
|
try {
|
|
try {
|
|
- dataNodeDiskChecker.checkDir(localFS, new Path(dir.toURI()));
|
|
|
|
- dirs.add(dir);
|
|
|
|
|
|
+ dataNodeDiskChecker.checkDir(localFS, new Path(location.getUri()));
|
|
|
|
+ locations.add(location);
|
|
} catch (IOException ioe) {
|
|
} catch (IOException ioe) {
|
|
LOG.warn("Invalid " + DFS_DATANODE_DATA_DIR_KEY + " "
|
|
LOG.warn("Invalid " + DFS_DATANODE_DATA_DIR_KEY + " "
|
|
- + dir + " : ", ioe);
|
|
|
|
- invalidDirs.append("\"").append(dir.getCanonicalPath()).append("\" ");
|
|
|
|
|
|
+ + location.getFile() + " : ", ioe);
|
|
|
|
+ invalidDirs.append("\"").append(location.getFile().getCanonicalPath()).append("\" ");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if (dirs.size() == 0) {
|
|
|
|
|
|
+ if (locations.size() == 0) {
|
|
throw new IOException("All directories in "
|
|
throw new IOException("All directories in "
|
|
+ DFS_DATANODE_DATA_DIR_KEY + " are invalid: "
|
|
+ DFS_DATANODE_DATA_DIR_KEY + " are invalid: "
|
|
+ invalidDirs);
|
|
+ invalidDirs);
|
|
}
|
|
}
|
|
- return dirs;
|
|
|
|
|
|
+ return locations;
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|