use of alluxio.exception.InvalidPathException 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;
}
use of alluxio.exception.InvalidPathException 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);
}
use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.
the class AlluxioFuseFileSystem method getattr.
/**
* Retrieves file attributes.
*
* @param path The path on the FS of the file
* @param stat FUSE data structure to fill with file attrs
* @return 0 on success, negative value on error
*/
@Override
public int getattr(String path, FileStat stat) {
final AlluxioURI turi = mPathResolverCache.getUnchecked(path);
LOG.trace("getattr({}) [Alluxio: {}]", path, turi);
try {
if (!mFileSystem.exists(turi)) {
return -ErrorCodes.ENOENT();
}
final URIStatus status = mFileSystem.getStatus(turi);
stat.st_size.set(status.getLength());
final long ctime_sec = status.getLastModificationTimeMs() / 1000;
//keeps only the "residual" nanoseconds not caputred in
// citme_sec
final long ctime_nsec = (status.getLastModificationTimeMs() % 1000) * 1000;
stat.st_ctim.tv_sec.set(ctime_sec);
stat.st_ctim.tv_nsec.set(ctime_nsec);
stat.st_mtim.tv_sec.set(ctime_sec);
stat.st_mtim.tv_nsec.set(ctime_nsec);
// TODO(andreareale): understand how to map FileInfo#getOwner()
// and FileInfo#getGroup() to UIDs and GIDs of the node
// where alluxio-fuse is mounted.
// While this is not done, just use uid and gid of the user
// running alluxio-fuse.
stat.st_uid.set(UID_AND_GID[0]);
stat.st_gid.set(UID_AND_GID[1]);
final int mode;
if (status.isFolder()) {
mode = FileStat.S_IFDIR;
} else {
mode = FileStat.S_IFREG;
}
stat.st_mode.set(mode);
} catch (InvalidPathException e) {
LOG.debug("Invalid path {}", path, e);
return -ErrorCodes.ENOENT();
} catch (FileDoesNotExistException e) {
LOG.debug("File does not exist {}", path, e);
return -ErrorCodes.ENOENT();
} catch (IOException e) {
LOG.error("IOException on {}", path, e);
return -ErrorCodes.EIO();
} catch (AlluxioException e) {
LOG.error("AlluxioException on {}", path, e);
return -ErrorCodes.EFAULT();
} catch (Throwable e) {
LOG.error("Unexpected exception on {}", path, e);
return -ErrorCodes.EFAULT();
}
return 0;
}
use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.
the class AlluxioFuseFileSystem method readdir.
/**
* Reads the contents of a directory.
*
* @param path The FS path of the directory
* @param buff The FUSE buffer to fill
* @param filter FUSE filter
* @param offset Ignored in alluxio-fuse
* @param fi FileInfo data structure kept by FUSE
* @return 0 on success, a negative value on error
*/
@Override
public int readdir(String path, Pointer buff, FuseFillDir filter, @off_t long offset, FuseFileInfo fi) {
final AlluxioURI turi = mPathResolverCache.getUnchecked(path);
LOG.trace("readdir({}) [Alluxio: {}]", path, turi);
try {
if (!mFileSystem.exists(turi)) {
return -ErrorCodes.ENOENT();
}
final URIStatus status = mFileSystem.getStatus(turi);
if (!status.isFolder()) {
return -ErrorCodes.ENOTDIR();
}
final List<URIStatus> ls = mFileSystem.listStatus(turi);
// standard . and .. entries
filter.apply(buff, ".", null, 0);
filter.apply(buff, "..", null, 0);
for (final URIStatus file : ls) {
filter.apply(buff, file.getName(), null, 0);
}
} catch (FileDoesNotExistException e) {
LOG.debug("File does not exist {}", path, e);
return -ErrorCodes.ENOENT();
} catch (InvalidPathException e) {
LOG.debug("Invalid path {}", path, e);
return -ErrorCodes.ENOENT();
} catch (IOException e) {
LOG.error("IOException on {}", path, e);
return -ErrorCodes.EIO();
} catch (AlluxioException e) {
LOG.error("AlluxioException on {}", path, e);
return -ErrorCodes.EFAULT();
} catch (Throwable e) {
LOG.error("Unexpected exception on {}", path, e);
return -ErrorCodes.EFAULT();
}
return 0;
}
use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.
the class KeyValueMaster method createStore.
/**
* Creates a new key-value store.
*
* @param path URI of the key-value store
* @throws FileAlreadyExistsException if a key-value store URI exists
* @throws InvalidPathException if the given path is invalid
* @throws AccessControlException if permission checking fails
*/
public synchronized void createStore(AlluxioURI path) throws FileAlreadyExistsException, InvalidPathException, AccessControlException {
try {
// Create this dir
mFileSystemMaster.createDirectory(path, CreateDirectoryOptions.defaults().setRecursive(true));
} catch (IOException e) {
// TODO(binfan): Investigate why {@link mFileSystemMaster.createDirectory} throws IOException
throw new InvalidPathException(String.format("Failed to createStore: can not create path %s", path), e);
} catch (FileDoesNotExistException e) {
// This should be impossible since we pass the recursive option into mkdir
throw Throwables.propagate(e);
}
long fileId = mFileSystemMaster.getFileId(path);
Preconditions.checkState(fileId != IdUtils.INVALID_FILE_ID);
createStoreInternal(fileId);
writeJournalEntry(newCreateStoreEntry(fileId));
flushJournal();
}
Aggregations