Search in sources :

Example 1 with Inode

use of alluxio.master.file.meta.Inode in project alluxio by Alluxio.

the class PermissionChecker method getPermissionInternal.

/**
   * Gets the permission to access an inode path given a user and its groups.
   *
   * @param user the user
   * @param groups the groups this user belongs to
   * @param path the inode path
   * @param inodeList the list of inodes in the path
   * @return the permission
   */
private Mode.Bits getPermissionInternal(String user, List<String> groups, String path, List<Inode<?>> inodeList) {
    int size = inodeList.size();
    Preconditions.checkArgument(size > 0, PreconditionMessage.EMPTY_FILE_INFO_LIST_FOR_PERMISSION_CHECK);
    // bypass checking permission for super user or super group of Alluxio file system.
    if (isPrivilegedUser(user, groups)) {
        return Mode.Bits.ALL;
    }
    // traverses from root to the parent dir to all inodes included by this path are executable
    for (int i = 0; i < size - 1; i++) {
        try {
            checkInode(user, groups, inodeList.get(i), Mode.Bits.EXECUTE, path);
        } catch (AccessControlException e) {
            return Mode.Bits.NONE;
        }
    }
    Inode inode = inodeList.get(inodeList.size() - 1);
    if (inode == null) {
        return Mode.Bits.NONE;
    }
    Mode.Bits mode = Mode.Bits.NONE;
    short permission = inode.getMode();
    if (user.equals(inode.getOwner())) {
        mode = mode.or(Mode.extractOwnerBits(permission));
    }
    if (groups.contains(inode.getGroup())) {
        mode = mode.or(Mode.extractGroupBits(permission));
    }
    mode = mode.or(Mode.extractOtherBits(permission));
    return mode;
}
Also used : Inode(alluxio.master.file.meta.Inode) Mode(alluxio.security.authorization.Mode) AccessControlException(alluxio.exception.AccessControlException)

Example 2 with Inode

use of alluxio.master.file.meta.Inode in project alluxio by Alluxio.

the class PermissionCheckTest method getLockedInodePath.

private LockedInodePath getLockedInodePath(ArrayList<Triple<String, String, Mode>> permissions) throws Exception {
    List<Inode<?>> inodes = new ArrayList<>();
    inodes.add(getRootInode());
    if (permissions.size() == 0) {
        return new MutableLockedInodePath(new AlluxioURI("/"), inodes, null);
    }
    String uri = "";
    for (int i = 0; i < permissions.size(); i++) {
        Triple<String, String, Mode> permission = permissions.get(i);
        String owner = permission.getLeft();
        String group = permission.getMiddle();
        Mode mode = permission.getRight();
        uri += "/" + (i + 1);
        if (i == permissions.size() - 1) {
            Inode<?> inode = InodeFile.create(i + 1, i, (i + 1) + "", CommonUtils.getCurrentMs(), CreateFileOptions.defaults().setBlockSizeBytes(Constants.KB).setOwner(owner).setGroup(group).setMode(mode));
            inodes.add(inode);
        } else {
            Inode<?> inode = InodeDirectory.create(i + 1, i, (i + 1) + "", CreateDirectoryOptions.defaults().setOwner(owner).setGroup(group).setMode(mode));
            inodes.add(inode);
        }
    }
    return new MutableLockedInodePath(new AlluxioURI(uri), inodes, null);
}
Also used : Inode(alluxio.master.file.meta.Inode) Mode(alluxio.security.authorization.Mode) ArrayList(java.util.ArrayList) MutableLockedInodePath(alluxio.master.file.meta.MutableLockedInodePath) AlluxioURI(alluxio.AlluxioURI)

Example 3 with Inode

use of alluxio.master.file.meta.Inode in project alluxio by Alluxio.

the class FileSystemMaster method propagatePersistedInternal.

/**
   * Propagates the persisted status to all parents of the given inode in the same mount partition.
   *
   * @param inodePath the inode to start the propagation at
   * @param replayed whether the invocation is a result of replaying the journal
   * @return list of inodes which were marked as persisted
   * @throws FileDoesNotExistException if a non-existent file is encountered
   */
private List<Inode<?>> propagatePersistedInternal(LockedInodePath inodePath, boolean replayed) throws FileDoesNotExistException {
    Inode<?> inode = inodePath.getInode();
    if (!inode.isPersisted()) {
        return Collections.emptyList();
    }
    List<Inode<?>> inodes = inodePath.getInodeList();
    // Traverse the inodes from target inode to the root.
    Collections.reverse(inodes);
    // Skip the first, to not examine the target inode itself.
    inodes = inodes.subList(1, inodes.size());
    List<Inode<?>> persistedInodes = new ArrayList<>();
    for (Inode<?> handle : inodes) {
        // the path is already locked.
        AlluxioURI path = mInodeTree.getPath(handle);
        if (mMountTable.isMountPoint(path)) {
            // Stop propagating the persisted status at mount points.
            break;
        }
        if (handle.isPersisted()) {
            // Stop if a persisted directory is encountered.
            break;
        }
        handle.setPersistenceState(PersistenceState.PERSISTED);
        if (!replayed) {
            persistedInodes.add(inode);
        }
    }
    return persistedInodes;
}
Also used : Inode(alluxio.master.file.meta.Inode) ArrayList(java.util.ArrayList) AlluxioURI(alluxio.AlluxioURI)

Example 4 with Inode

use of alluxio.master.file.meta.Inode in project alluxio by Alluxio.

the class FileSystemMaster method startupCheckConsistency.

/**
   * Checks the consistency of the root in a multi-threaded and incremental fashion. This method
   * will only READ lock the directories and files actively being checked and release them after the
   * check on the file / directory is complete.
   *
   * @return a list of paths in Alluxio which are not consistent with the under storage
   * @throws InterruptedException if the thread is interrupted during execution
   * @throws IOException if an error occurs interacting with the under storage
   */
private List<AlluxioURI> startupCheckConsistency(final ExecutorService service) throws InterruptedException, IOException {
    /** A marker {@link StartupConsistencyChecker}s add to the queue to signal completion */
    final long completionMarker = -1;
    /** A shared queue of directories which have yet to be checked */
    final BlockingQueue<Long> dirsToCheck = new LinkedBlockingQueue<>();
    /**
     * A {@link Callable} which checks the consistency of a directory.
     */
    final class StartupConsistencyChecker implements Callable<List<AlluxioURI>> {

        /** The path to check, guaranteed to be a directory in Alluxio. */
        private final Long mFileId;

        /**
       * Creates a new callable which checks the consistency of a directory.
       * @param fileId the path to check
       */
        private StartupConsistencyChecker(Long fileId) {
            mFileId = fileId;
        }

        /**
       * Checks the consistency of the directory and all immediate children which are files. All
       * immediate children which are directories are added to the shared queue of directories to
       * check. The parent directory is READ locked during the entire call while the children are
       * READ locked only during the consistency check of the children files.
       *
       * @return a list of inconsistent uris
       * @throws IOException if an error occurs interacting with the under storage
       */
        @Override
        public List<AlluxioURI> call() throws IOException {
            List<AlluxioURI> inconsistentUris = new ArrayList<>();
            try (LockedInodePath dir = mInodeTree.lockFullInodePath(mFileId, InodeTree.LockMode.READ)) {
                Inode parentInode = dir.getInode();
                AlluxioURI parentUri = dir.getUri();
                if (!checkConsistencyInternal(parentInode, parentUri)) {
                    inconsistentUris.add(parentUri);
                }
                for (Inode childInode : ((InodeDirectory) parentInode).getChildren()) {
                    try {
                        childInode.lockReadAndCheckParent(parentInode);
                    } catch (InvalidPathException e) {
                        // This should be safe, continue.
                        LOG.debug("Error during startup check consistency, ignoring and continuing.", e);
                        continue;
                    }
                    try {
                        AlluxioURI childUri = parentUri.join(childInode.getName());
                        if (childInode.isDirectory()) {
                            dirsToCheck.add(childInode.getId());
                        } else {
                            if (!checkConsistencyInternal(childInode, childUri)) {
                                inconsistentUris.add(childUri);
                            }
                        }
                    } finally {
                        childInode.unlockRead();
                    }
                }
            } catch (FileDoesNotExistException e) {
                // This should be safe, continue.
                LOG.debug("A file scheduled for consistency check was deleted before the check.");
            } catch (InvalidPathException e) {
                // This should not happen.
                LOG.error("An invalid path was discovered during the consistency check, skipping.", e);
            }
            dirsToCheck.add(completionMarker);
            return inconsistentUris;
        }
    }
    // Add the root to the directories to check.
    dirsToCheck.add(mInodeTree.getRoot().getId());
    List<Future<List<AlluxioURI>>> results = new ArrayList<>();
    // Tracks how many checkers have been started.
    long started = 0;
    // Tracks how many checkers have completed.
    long completed = 0;
    do {
        Long fileId = dirsToCheck.take();
        if (fileId == completionMarker) {
            // A thread signaled completion.
            completed++;
        } else {
            // A new directory needs to be checked.
            StartupConsistencyChecker checker = new StartupConsistencyChecker(fileId);
            results.add(service.submit(checker));
            started++;
        }
    } while (started != completed);
    // Return the total set of inconsistent paths discovered.
    List<AlluxioURI> inconsistentUris = new ArrayList<>();
    for (Future<List<AlluxioURI>> result : results) {
        try {
            inconsistentUris.addAll(result.get());
        } catch (Exception e) {
            // This shouldn't happen, all futures should be complete.
            Throwables.propagate(e);
        }
    }
    service.shutdown();
    return inconsistentUris;
}
Also used : FileDoesNotExistException(alluxio.exception.FileDoesNotExistException) ArrayList(java.util.ArrayList) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) InvalidPathException(alluxio.exception.InvalidPathException) Callable(java.util.concurrent.Callable) AlluxioException(alluxio.exception.AlluxioException) BlockInfoException(alluxio.exception.BlockInfoException) FileAlreadyExistsException(alluxio.exception.FileAlreadyExistsException) IOException(java.io.IOException) InvalidPathException(alluxio.exception.InvalidPathException) AccessControlException(alluxio.exception.AccessControlException) InvalidFileSizeException(alluxio.exception.InvalidFileSizeException) FileDoesNotExistException(alluxio.exception.FileDoesNotExistException) FileAlreadyCompletedException(alluxio.exception.FileAlreadyCompletedException) DirectoryNotEmptyException(alluxio.exception.DirectoryNotEmptyException) UnexpectedAlluxioException(alluxio.exception.UnexpectedAlluxioException) LockedInodePath(alluxio.master.file.meta.LockedInodePath) InodeDirectory(alluxio.master.file.meta.InodeDirectory) Inode(alluxio.master.file.meta.Inode) Future(java.util.concurrent.Future) ArrayList(java.util.ArrayList) InodeLockList(alluxio.master.file.meta.InodeLockList) List(java.util.List) TtlBucketList(alluxio.master.file.meta.TtlBucketList) PrefixList(alluxio.collections.PrefixList) AlluxioURI(alluxio.AlluxioURI)

Example 5 with Inode

use of alluxio.master.file.meta.Inode in project alluxio by Alluxio.

the class FileSystemMaster method renameAndJournal.

/**
   * Renames a file to a destination.
   * <p>
   * Writes to the journal.
   *
   * @param srcInodePath the source path to rename
   * @param dstInodePath the destination path to rename the file to
   * @param options method options
   * @param journalContext the journalContext
   * @throws InvalidPathException if an invalid path is encountered
   * @throws FileDoesNotExistException if a non-existent file is encountered
   * @throws FileAlreadyExistsException if the file already exists
   * @throws IOException if an I/O error occurs
   */
private void renameAndJournal(LockedInodePath srcInodePath, LockedInodePath dstInodePath, RenameOptions options, JournalContext journalContext) throws InvalidPathException, FileDoesNotExistException, FileAlreadyExistsException, IOException {
    if (!srcInodePath.fullPathExists()) {
        throw new FileDoesNotExistException(ExceptionMessage.PATH_DOES_NOT_EXIST.getMessage(srcInodePath.getUri()));
    }
    Inode<?> srcInode = srcInodePath.getInode();
    // Renaming path to itself is a no-op.
    if (srcInodePath.getUri().equals(dstInodePath.getUri())) {
        return;
    }
    // Renaming the root is not allowed.
    if (srcInodePath.getUri().isRoot()) {
        throw new InvalidPathException(ExceptionMessage.ROOT_CANNOT_BE_RENAMED.getMessage());
    }
    if (dstInodePath.getUri().isRoot()) {
        throw new InvalidPathException(ExceptionMessage.RENAME_CANNOT_BE_TO_ROOT.getMessage());
    }
    // Renaming across mount points is not allowed.
    String srcMount = mMountTable.getMountPoint(srcInodePath.getUri());
    String dstMount = mMountTable.getMountPoint(dstInodePath.getUri());
    if ((srcMount == null && dstMount != null) || (srcMount != null && dstMount == null) || (srcMount != null && dstMount != null && !srcMount.equals(dstMount))) {
        throw new InvalidPathException(ExceptionMessage.RENAME_CANNOT_BE_ACROSS_MOUNTS.getMessage(srcInodePath.getUri(), dstInodePath.getUri()));
    }
    // Renaming onto a mount point is not allowed.
    if (mMountTable.isMountPoint(dstInodePath.getUri())) {
        throw new InvalidPathException(ExceptionMessage.RENAME_CANNOT_BE_ONTO_MOUNT_POINT.getMessage(dstInodePath.getUri()));
    }
    // srcComponents isn't a prefix of dstComponents.
    if (PathUtils.hasPrefix(dstInodePath.getUri().getPath(), srcInodePath.getUri().getPath())) {
        throw new InvalidPathException(ExceptionMessage.RENAME_CANNOT_BE_TO_SUBDIRECTORY.getMessage(srcInodePath.getUri(), dstInodePath.getUri()));
    }
    // Get the inodes of the src and dst parents.
    Inode<?> srcParentInode = srcInodePath.getParentInodeDirectory();
    if (!srcParentInode.isDirectory()) {
        throw new InvalidPathException(ExceptionMessage.PATH_MUST_HAVE_VALID_PARENT.getMessage(srcInodePath.getUri()));
    }
    Inode<?> dstParentInode = dstInodePath.getParentInodeDirectory();
    if (!dstParentInode.isDirectory()) {
        throw new InvalidPathException(ExceptionMessage.PATH_MUST_HAVE_VALID_PARENT.getMessage(dstInodePath.getUri()));
    }
    // Make sure destination path does not exist
    if (dstInodePath.fullPathExists()) {
        throw new FileAlreadyExistsException(ExceptionMessage.FILE_ALREADY_EXISTS.getMessage(dstInodePath.getUri()));
    }
    // Now we remove srcInode from its parent and insert it into dstPath's parent
    renameInternal(srcInodePath, dstInodePath, false, options);
    List<Inode<?>> persistedInodes = propagatePersistedInternal(srcInodePath, false);
    journalPersistedInodes(persistedInodes, journalContext);
    RenameEntry rename = RenameEntry.newBuilder().setId(srcInode.getId()).setDstPath(dstInodePath.getUri().getPath()).setOpTimeMs(options.getOperationTimeMs()).build();
    appendJournalEntry(JournalEntry.newBuilder().setRename(rename).build(), journalContext);
}
Also used : FileDoesNotExistException(alluxio.exception.FileDoesNotExistException) RenameEntry(alluxio.proto.journal.File.RenameEntry) FileAlreadyExistsException(alluxio.exception.FileAlreadyExistsException) Inode(alluxio.master.file.meta.Inode) InvalidPathException(alluxio.exception.InvalidPathException)

Aggregations

Inode (alluxio.master.file.meta.Inode)42 AlluxioURI (alluxio.AlluxioURI)19 LockedInodePath (alluxio.master.file.meta.LockedInodePath)15 MountTable (alluxio.master.file.meta.MountTable)15 FileDoesNotExistException (alluxio.exception.FileDoesNotExistException)14 UnderFileSystem (alluxio.underfs.UnderFileSystem)13 ArrayList (java.util.ArrayList)13 AccessControlException (alluxio.exception.AccessControlException)12 InvalidPathException (alluxio.exception.InvalidPathException)12 InodeDirectory (alluxio.master.file.meta.InodeDirectory)11 IOException (java.io.IOException)11 UfsStatus (alluxio.underfs.UfsStatus)9 InodeFile (alluxio.master.file.meta.InodeFile)8 Fingerprint (alluxio.underfs.Fingerprint)8 BlockInfoException (alluxio.exception.BlockInfoException)7 DirectoryNotEmptyException (alluxio.exception.DirectoryNotEmptyException)6 FileAlreadyExistsException (alluxio.exception.FileAlreadyExistsException)6 UnexpectedAlluxioException (alluxio.exception.UnexpectedAlluxioException)6 FileAlreadyCompletedException (alluxio.exception.FileAlreadyCompletedException)5 InvalidFileSizeException (alluxio.exception.InvalidFileSizeException)5