在创建完本地文件系统(localFS)后,会进入数据目录的校验阶段,在这里checkDir是重头戏,下面会继续分析
public static DataNode makeInstance(String[] dataDirs,Configuration conf, SecureResources resources) throws IOException { //创建UGI信息 UserGroupInformation.setConfiguration(conf); //创建本地文件系统 LocalFileSystem localFS = FileSystem.getLocal(conf); //创建用于存放通过校验的数据目录 ArrayList<File> dirs = new ArrayList<File>(); //校验时所用到的权限,默认权限是755 FsPermission dataDirPermission = new FsPermission(conf.get(DATA_DIR_PERMISSION_KEY, DEFAULT_DATA_DIR_PERMISSION)); //数据目录可以配置多个,实际应用中如果有多个盘,那么会挂在不同的目录下,一起在hadoop中使用 for (String dir : dataDirs) { try { //开始校验 DiskChecker.checkDir(localFS, new Path(dir), dataDirPermission); //成功的目录会被记录下来 dirs.add(new File(dir)); } catch(IOException e) { //若有不成功的,则打印警告信息,当然还有全部失败的情况,看下面 LOG.warn("Invalid directory in " + DATA_DIR_KEY + ": " + e.getMessage()); } } //如果有成功的目录,则直接创建DataNode if (dirs.size() > 0) returnnew DataNode(conf, dirs, resources); //如果全部失败,则记录错误信息,并返回空 LOG.error("All directories in " + DATA_DIR_KEY + " are invalid."); returnnull; }
下面看checkDir做了什么,其实不看代码我们大概也能猜测出来,对目录的检测无非就是创建、删除、在内部创建文件、删除文件这些操作,当然这些操作都离不开权限信息
public staticvoid checkDir(LocalFileSystem localFS, Path dir, FsPermissionexpected) throws DiskErrorException, IOException { //1、测试能否创建该目录,如果存在则检测权限信息 if (!mkdirsWithExistsAndPermissionCheck(localFS,dir, expected)) thrownew DiskErrorException("can not create directory: " +dir.toString()); FileStatus stat =localFS.getFileStatus(dir); FsPermission actual = stat.getPermission(); //2、判断是否为目录 if (!stat.isDir()) thrownew DiskErrorException("not a directory: " +dir.toString()); //3、判断文件是否有读权限 FsAction user = actual.getUserAction(); if (!user.implies(FsAction.READ)) thrownew DiskErrorException("directory is not readable: " +dir.toString()); //4、判断文件是否有写权限 if (!user.implies(FsAction.WRITE)) thrownew DiskErrorException("directory is not writable: " +dir.toString()); }
1、 测试能否创建该目录,如果存在则检测权限信息
public static boolean mkdirsWithExistsAndPermissionCheck( LocalFileSystem localFS, Path dir,FsPermission expected) throws IOException { //将目录转化成文件 File directory = newFile(dir.makeQualified(localFS).toUri().getPath()); //如果目录不存在,则创建并授权 if (!directory.exists()) { boolean created = mkdirsWithExistsCheck(directory); if (created) { localFS.setPermission(dir, expected); returntrue; } else { returnfalse; } } //如果存在,则只检测权限信息,通常我们都会提前创建好,这里的权限校验比较简单,就是比较后面两个参数是否一致 checkPermission(dir, expected,localFS.getFileStatus(dir).getPermission()); return true; }