Search in sources :

Example 76 with InvalidPathException

use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.

the class DefaultFileSystemMaster method exists.

@Override
public boolean exists(AlluxioURI path, ExistsContext context) throws AccessControlException, IOException {
    try (RpcContext rpcContext = createRpcContext(context);
        FileSystemMasterAuditContext auditContext = createAuditContext("exists", path, null, null)) {
        syncMetadata(rpcContext, path, context.getOptions().getCommonOptions(), DescendantType.ONE, auditContext, LockedInodePath::getInodeOrNull, (inodePath, permChecker) -> permChecker.checkPermission(Mode.Bits.READ, inodePath), false);
        try (LockedInodePath inodePath = mInodeTree.lockInodePath(createLockingScheme(path, context.getOptions().getCommonOptions(), LockPattern.READ))) {
            LoadMetadataContext lmCtx = LoadMetadataContext.create(LoadMetadataPOptions.newBuilder().setCommonOptions(context.getOptions().getCommonOptions()).setLoadType(context.getOptions().getLoadMetadataType()));
            if (shouldLoadMetadataIfNotExists(inodePath, lmCtx)) {
                checkLoadMetadataOptions(context.getOptions().getLoadMetadataType(), path);
                loadMetadataIfNotExist(rpcContext, path, lmCtx, false);
            }
        } catch (FileDoesNotExistException e) {
            return false;
        }
        try (LockedInodePath inodePath = mInodeTree.lockInodePath(createLockingScheme(path, context.getOptions().getCommonOptions(), LockPattern.READ))) {
            auditContext.setSucceeded(true);
            return inodePath.fullPathExists();
        }
    } catch (InvalidPathException e) {
        return false;
    }
}
Also used : LockedInodePath(alluxio.master.file.meta.LockedInodePath) FileDoesNotExistException(alluxio.exception.FileDoesNotExistException) LoadMetadataContext(alluxio.master.file.contexts.LoadMetadataContext) InvalidPathException(alluxio.exception.InvalidPathException)

Example 77 with InvalidPathException

use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.

the class DefaultFileSystemMaster method getInMemoryFiles.

@Override
public List<AlluxioURI> getInMemoryFiles() throws UnavailableException {
    List<AlluxioURI> files = new ArrayList<>();
    LockedInodePath rootPath;
    try {
        rootPath = mInodeTree.lockFullInodePath(new AlluxioURI(AlluxioURI.SEPARATOR), LockPattern.READ);
    } catch (FileDoesNotExistException | InvalidPathException e) {
        // Root should always exist.
        throw new RuntimeException(e);
    }
    try (LockedInodePath inodePath = rootPath) {
        getInMemoryFilesInternal(inodePath, files);
    }
    return files;
}
Also used : LockedInodePath(alluxio.master.file.meta.LockedInodePath) FileDoesNotExistException(alluxio.exception.FileDoesNotExistException) ArrayList(java.util.ArrayList) InvalidPathException(alluxio.exception.InvalidPathException) AlluxioURI(alluxio.AlluxioURI)

Example 78 with InvalidPathException

use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.

the class DefaultFileSystemMaster method getFileIdInternal.

private long getFileIdInternal(AlluxioURI path, boolean checkPermission) throws AccessControlException, UnavailableException {
    try (RpcContext rpcContext = createRpcContext()) {
        /*
      In order to prevent locking twice on RPCs where metadata does _not_ need to be loaded, we use
      a two-step scheme as an optimization to prevent the extra lock. loadMetadataIfNotExists
      requires a lock on the tree to determine if the path should be loaded before executing. To
      prevent the extra lock, we execute the RPC as normal and use a conditional check in the
      main body of the function to determine whether control flow should be shifted out of the
      RPC logic and back to the loadMetadataIfNotExists function.

      If loadMetadataIfNotExists runs, then the next pass into the main logic body should
      continue as normal. This may present a slight decrease in performance for newly-loaded
      metadata, but it is better than affecting the most common case where metadata is not being
      loaded.
       */
        LoadMetadataContext lmCtx = LoadMetadataContext.mergeFrom(LoadMetadataPOptions.newBuilder().setCreateAncestors(true));
        boolean run = true;
        boolean loadMetadata = false;
        while (run) {
            run = false;
            if (loadMetadata) {
                loadMetadataIfNotExist(rpcContext, path, lmCtx, false);
            }
            try (LockedInodePath inodePath = mInodeTree.lockInodePath(path, LockPattern.READ)) {
                if (checkPermission) {
                    mPermissionChecker.checkPermission(Mode.Bits.READ, inodePath);
                }
                if (!loadMetadata && shouldLoadMetadataIfNotExists(inodePath, lmCtx)) {
                    loadMetadata = true;
                    run = true;
                    continue;
                }
                mInodeTree.ensureFullInodePath(inodePath);
                return inodePath.getInode().getId();
            } catch (InvalidPathException | FileDoesNotExistException e) {
                return IdUtils.INVALID_FILE_ID;
            }
        }
    } catch (InvalidPathException e) {
        return IdUtils.INVALID_FILE_ID;
    }
    return IdUtils.INVALID_FILE_ID;
}
Also used : LockedInodePath(alluxio.master.file.meta.LockedInodePath) FileDoesNotExistException(alluxio.exception.FileDoesNotExistException) LoadMetadataContext(alluxio.master.file.contexts.LoadMetadataContext) InvalidPathException(alluxio.exception.InvalidPathException)

Example 79 with InvalidPathException

use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.

the class InodeSyncStream method sync.

/**
 * Sync the metadata according the root path the stream was created with.
 *
 * @return SyncStatus object
 */
public SyncStatus sync() throws AccessControlException, InvalidPathException {
    // The high-level process for the syncing is:
    // 1. Given an Alluxio path, determine if it is not consistent with the corresponding UFS path.
    // this means the UFS path does not exist, or has metadata which differs from Alluxio
    // 2. If only the metadata changed, update the inode with the new metadata
    // 3. If the path does not exist in the UFS, delete the inode in Alluxio
    // 4. If not deleted, load metadata from the UFS
    // 5. If a recursive sync, add children inodes to sync queue
    int syncPathCount = 0;
    int failedSyncPathCount = 0;
    // stop syncing when we've processed this many paths. -1 for infinite
    int stopNum = -1;
    if (!mRootScheme.shouldSync() && !mForceSync) {
        return SyncStatus.NOT_NEEDED;
    }
    Instant start = Instant.now();
    try (LockedInodePath path = mInodeTree.lockInodePath(mRootScheme)) {
        if (mAuditContext != null && mAuditContextSrcInodeFunc != null) {
            mAuditContext.setSrcInode(mAuditContextSrcInodeFunc.apply(path));
        }
        syncInodeMetadata(path);
        syncPathCount++;
        if (mDescendantType == DescendantType.ONE) {
            // If descendantType is ONE, then we shouldn't process any more paths except for those
            // currently in the queue
            stopNum = mPendingPaths.size();
        }
        // process the sync result for the original path
        try {
            path.traverse();
        } catch (InvalidPathException e) {
            throw new RuntimeException(e);
        }
    } catch (BlockInfoException | FileAlreadyCompletedException | FileDoesNotExistException | InterruptedException | InvalidFileSizeException | IOException e) {
        LogUtils.warnWithException(LOG, "Failed to sync metadata on root path {}", toString(), e);
        failedSyncPathCount++;
    } finally {
        // regardless of the outcome, remove the UfsStatus for this path from the cache
        mStatusCache.remove(mRootScheme.getPath());
    }
    // Process any children after the root.
    while (!mPendingPaths.isEmpty() || !mSyncPathJobs.isEmpty()) {
        if (Thread.currentThread().isInterrupted()) {
            LOG.warn("Metadata syncing was interrupted before completion; {}", toString());
            break;
        }
        if (mRpcContext.isCancelled()) {
            LOG.warn("Metadata syncing was cancelled before completion; {}", toString());
            break;
        }
        // successfully
        while (true) {
            Future<Boolean> job = mSyncPathJobs.peek();
            if (job == null || !job.isDone()) {
                break;
            }
            // remove the job because we know it is done.
            if (mSyncPathJobs.poll() != job) {
                throw new ConcurrentModificationException("Head of queue modified while executing");
            }
            try {
                // This shouldn't block because we checked job.isDone() earlier
                if (job.get()) {
                    syncPathCount++;
                } else {
                    failedSyncPathCount++;
                }
            } catch (InterruptedException | ExecutionException e) {
                failedSyncPathCount++;
                LogUtils.warnWithException(LOG, "metadata sync failed while polling for finished paths; {}", toString(), e);
                if (e instanceof InterruptedException) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }
        // When using descendant type of ONE, we need to stop prematurely.
        if (stopNum != -1 && (syncPathCount + failedSyncPathCount) > stopNum) {
            break;
        }
        // We can submit up to ( max_concurrency - <jobs queue size>) jobs back into the queue
        int submissions = mConcurrencyLevel - mSyncPathJobs.size();
        for (int i = 0; i < submissions; i++) {
            AlluxioURI path = mPendingPaths.poll();
            if (path == null) {
                // no paths left to sync
                break;
            }
            Future<Boolean> job = mMetadataSyncService.submit(() -> processSyncPath(path));
            mSyncPathJobs.offer(job);
        }
        // After submitting all jobs wait for the job at the head of the queue to finish.
        Future<Boolean> oldestJob = mSyncPathJobs.peek();
        if (oldestJob == null) {
            // There might not be any jobs, restart the loop.
            continue;
        }
        try {
            // block until the oldest job finished.
            oldestJob.get();
        } catch (InterruptedException | ExecutionException e) {
            LogUtils.warnWithException(LOG, "Exception while waiting for oldest metadata sync job to finish: {}", toString(), e);
            if (e instanceof InterruptedException) {
                Thread.currentThread().interrupt();
            }
        }
    }
    if (LOG.isDebugEnabled()) {
        Instant end = Instant.now();
        Duration elapsedTime = Duration.between(start, end);
        LOG.debug("synced {} paths ({} success, {} failed) in {} ms on {}", syncPathCount + failedSyncPathCount, syncPathCount, failedSyncPathCount, elapsedTime.toMillis(), mRootScheme);
    }
    boolean success = syncPathCount > 0;
    if (ServerConfiguration.getBoolean(PropertyKey.MASTER_METADATA_SYNC_REPORT_FAILURE)) {
        // There should not be any failed or outstanding jobs
        success = (failedSyncPathCount == 0) && mSyncPathJobs.isEmpty() && mPendingPaths.isEmpty();
    }
    if (success) {
        // update the sync path cache for the root of the sync
        // TODO(gpang): Do we need special handling for failures and thread interrupts?
        mUfsSyncPathCache.notifySyncedPath(mRootScheme.getPath().getPath(), mDescendantType);
    }
    mStatusCache.cancelAllPrefetch();
    mSyncPathJobs.forEach(f -> f.cancel(true));
    return success ? SyncStatus.OK : SyncStatus.FAILED;
}
Also used : FileDoesNotExistException(alluxio.exception.FileDoesNotExistException) ConcurrentModificationException(java.util.ConcurrentModificationException) Instant(java.time.Instant) BlockInfoException(alluxio.exception.BlockInfoException) Duration(java.time.Duration) IOException(java.io.IOException) Fingerprint(alluxio.underfs.Fingerprint) InvalidPathException(alluxio.exception.InvalidPathException) LockedInodePath(alluxio.master.file.meta.LockedInodePath) InvalidFileSizeException(alluxio.exception.InvalidFileSizeException) FileAlreadyCompletedException(alluxio.exception.FileAlreadyCompletedException) ExecutionException(java.util.concurrent.ExecutionException) AlluxioURI(alluxio.AlluxioURI)

Example 80 with InvalidPathException

use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.

the class DefaultFileSystemMaster method unmountInternal.

/**
 * Unmounts a UFS path previously mounted onto an Alluxio path.
 *
 * This method does not delete blocks. Instead, it adds the to the passed-in block deletion
 * context so that the blocks can be deleted after the inode deletion journal entry has been
 * written. We cannot delete blocks earlier because the inode deletion may fail, leaving us with
 * inode containing deleted blocks.
 *
 * @param rpcContext the rpc context
 * @param inodePath the Alluxio path to unmount, must be a mount point
 */
private void unmountInternal(RpcContext rpcContext, LockedInodePath inodePath) throws InvalidPathException, FileDoesNotExistException, IOException {
    if (!inodePath.fullPathExists()) {
        throw new FileDoesNotExistException("Failed to unmount: Path " + inodePath.getUri() + " does not exist");
    }
    MountInfo mountInfo = mMountTable.getMountTable().get(inodePath.getUri().getPath());
    if (mountInfo == null) {
        throw new InvalidPathException("Failed to unmount " + inodePath.getUri() + ". Please ensure" + " the path is an existing mount point.");
    }
    mSyncManager.stopSyncForMount(mountInfo.getMountId());
    if (!mMountTable.delete(rpcContext, inodePath.getUri(), true)) {
        throw new InvalidPathException("Failed to unmount " + inodePath.getUri() + ". Please ensure" + " the path is an existing mount point and not root.");
    }
    try {
        // Use the internal delete API, setting {@code alluxioOnly} to true to prevent the delete
        // operations from being persisted in the UFS.
        deleteInternal(rpcContext, inodePath, DeleteContext.mergeFrom(DeletePOptions.newBuilder().setRecursive(true).setAlluxioOnly(true)));
    } catch (DirectoryNotEmptyException e) {
        throw new RuntimeException(String.format("We should never see this exception because %s should never be thrown when recursive " + "is true.", e.getClass()));
    }
}
Also used : FileDoesNotExistException(alluxio.exception.FileDoesNotExistException) DirectoryNotEmptyException(alluxio.exception.DirectoryNotEmptyException) MountInfo(alluxio.master.file.meta.options.MountInfo) InvalidPathException(alluxio.exception.InvalidPathException)

Aggregations

InvalidPathException (alluxio.exception.InvalidPathException)82 AlluxioURI (alluxio.AlluxioURI)51 FileDoesNotExistException (alluxio.exception.FileDoesNotExistException)44 IOException (java.io.IOException)40 ArrayList (java.util.ArrayList)25 FileAlreadyExistsException (alluxio.exception.FileAlreadyExistsException)19 AccessControlException (alluxio.exception.AccessControlException)17 AlluxioException (alluxio.exception.AlluxioException)17 LockedInodePath (alluxio.master.file.meta.LockedInodePath)17 MountTable (alluxio.master.file.meta.MountTable)14 UnderFileSystem (alluxio.underfs.UnderFileSystem)14 Inode (alluxio.master.file.meta.Inode)12 MountInfo (alluxio.master.file.meta.options.MountInfo)11 BlockInfoException (alluxio.exception.BlockInfoException)10 UnavailableException (alluxio.exception.status.UnavailableException)9 LockResource (alluxio.resource.LockResource)9 DirectoryNotEmptyException (alluxio.exception.DirectoryNotEmptyException)8 InodeDirectory (alluxio.master.file.meta.InodeDirectory)8 Test (org.junit.Test)8 URIStatus (alluxio.client.file.URIStatus)7