use of alluxio.resource.LockResource in project alluxio by Alluxio.
the class MountTable method add.
/**
* Mounts the given UFS path at the given Alluxio path. The Alluxio path should not be nested
* under an existing mount point.
*
* @param alluxioUri an Alluxio path URI
* @param ufsUri a UFS path URI
* @param options the mount options
* @throws FileAlreadyExistsException if the mount point already exists
* @throws InvalidPathException if an invalid path is encountered
*/
public void add(AlluxioURI alluxioUri, AlluxioURI ufsUri, MountOptions options) throws FileAlreadyExistsException, InvalidPathException {
String alluxioPath = alluxioUri.getPath();
LOG.info("Mounting {} at {}", ufsUri, alluxioPath);
try (LockResource r = new LockResource(mWriteLock)) {
if (mMountTable.containsKey(alluxioPath)) {
throw new FileAlreadyExistsException(ExceptionMessage.MOUNT_POINT_ALREADY_EXISTS.getMessage(alluxioPath));
}
// or suffix of any existing mount path.
for (Map.Entry<String, MountInfo> entry : mMountTable.entrySet()) {
String mountedAlluxioPath = entry.getKey();
AlluxioURI mountedUfsUri = entry.getValue().getUfsUri();
if (!mountedAlluxioPath.equals(ROOT) && PathUtils.hasPrefix(alluxioPath, mountedAlluxioPath)) {
throw new InvalidPathException(ExceptionMessage.MOUNT_POINT_PREFIX_OF_ANOTHER.getMessage(mountedAlluxioPath, alluxioPath));
}
if ((ufsUri.getScheme() == null || ufsUri.getScheme().equals(mountedUfsUri.getScheme())) && (ufsUri.getAuthority() == null || ufsUri.getAuthority().equals(mountedUfsUri.getAuthority()))) {
String ufsPath = ufsUri.getPath();
String mountedUfsPath = mountedUfsUri.getPath();
if (PathUtils.hasPrefix(ufsPath, mountedUfsPath)) {
throw new InvalidPathException(ExceptionMessage.MOUNT_POINT_PREFIX_OF_ANOTHER.getMessage(mountedUfsUri.toString(), ufsUri.toString()));
}
if (PathUtils.hasPrefix(mountedUfsPath, ufsPath)) {
throw new InvalidPathException(ExceptionMessage.MOUNT_POINT_PREFIX_OF_ANOTHER.getMessage(ufsUri.toString(), mountedUfsUri.toString()));
}
}
}
mMountTable.put(alluxioPath, new MountInfo(ufsUri, options));
}
}
use of alluxio.resource.LockResource in project alluxio by Alluxio.
the class TieredBlockStore method cleanupSession.
@Override
public void cleanupSession(long sessionId) {
// Release all locks the session is holding.
mLockManager.cleanupSession(sessionId);
// Collect a list of temp blocks the given session owns and abort all of them with best effort
List<TempBlockMeta> tempBlocksToRemove;
try (LockResource r = new LockResource(mMetadataReadLock)) {
tempBlocksToRemove = mMetaManager.getSessionTempBlocks(sessionId);
}
for (TempBlockMeta tempBlockMeta : tempBlocksToRemove) {
try {
LOG.warn("Clean up expired temporary block {} from session {}.", tempBlockMeta.getBlockId(), sessionId);
abortBlockInternal(sessionId, tempBlockMeta.getBlockId());
} catch (Exception e) {
LOG.error("Failed to cleanup tempBlock {} due to {}", tempBlockMeta.getBlockId(), e.getMessage());
}
}
}
use of alluxio.resource.LockResource in project alluxio by Alluxio.
the class TieredBlockStore method removeBlockInternal.
/**
* Removes a block.
*
* @param sessionId session Id
* @param blockId block Id
* @param location the source location of the block
* @throws InvalidWorkerStateException if the block to remove is a temp block
* @throws BlockDoesNotExistException if this block can not be found
* @throws IOException if I/O errors occur when removing this block file
*/
private void removeBlockInternal(long sessionId, long blockId, BlockStoreLocation location) throws InvalidWorkerStateException, BlockDoesNotExistException, IOException {
long lockId = mLockManager.lockBlock(sessionId, blockId, BlockLockType.WRITE);
try {
String filePath;
BlockMeta blockMeta;
try (LockResource r = new LockResource(mMetadataReadLock)) {
if (mMetaManager.hasTempBlockMeta(blockId)) {
throw new InvalidWorkerStateException(ExceptionMessage.REMOVE_UNCOMMITTED_BLOCK, blockId);
}
blockMeta = mMetaManager.getBlockMeta(blockId);
filePath = blockMeta.getPath();
}
if (!blockMeta.getBlockLocation().belongsTo(location)) {
throw new BlockDoesNotExistException(ExceptionMessage.BLOCK_NOT_FOUND_AT_LOCATION, blockId, location);
}
// Heavy IO is guarded by block lock but not metadata lock. This may throw IOException.
Files.delete(Paths.get(filePath));
try (LockResource r = new LockResource(mMetadataWriteLock)) {
mMetaManager.removeBlockMeta(blockMeta);
} catch (BlockDoesNotExistException e) {
// we shall never reach here
throw Throwables.propagate(e);
}
} finally {
mLockManager.unlockBlock(lockId);
}
}
use of alluxio.resource.LockResource in project alluxio by Alluxio.
the class TieredBlockStore method freeSpaceInternal.
/**
* Tries to get an eviction plan to free a certain amount of space in the given location, and
* carries out this plan with the best effort.
*
* @param sessionId the session Id
* @param availableBytes amount of space in bytes to free
* @param location location of space
* @throws WorkerOutOfSpaceException if it is impossible to achieve the free requirement
* @throws IOException if I/O errors occur when removing or moving block files
*/
private void freeSpaceInternal(long sessionId, long availableBytes, BlockStoreLocation location) throws WorkerOutOfSpaceException, IOException {
EvictionPlan plan;
try (LockResource r = new LockResource(mMetadataReadLock)) {
plan = mEvictor.freeSpaceWithView(availableBytes, location, getUpdatedView());
// Absent plan means failed to evict enough space.
if (plan == null) {
throw new WorkerOutOfSpaceException(ExceptionMessage.NO_EVICTION_PLAN_TO_FREE_SPACE);
}
}
// 1. remove blocks to make room.
for (Pair<Long, BlockStoreLocation> blockInfo : plan.toEvict()) {
try {
removeBlockInternal(sessionId, blockInfo.getFirst(), blockInfo.getSecond());
} catch (InvalidWorkerStateException e) {
// Evictor is not working properly
LOG.error("Failed to evict blockId {}, this is temp block", blockInfo.getFirst());
continue;
} catch (BlockDoesNotExistException e) {
LOG.info("Failed to evict blockId {}, it could be already deleted", blockInfo.getFirst());
continue;
}
synchronized (mBlockStoreEventListeners) {
for (BlockStoreEventListener listener : mBlockStoreEventListeners) {
listener.onRemoveBlockByWorker(sessionId, blockInfo.getFirst());
}
}
}
// 2. transfer blocks among tiers.
// 2.1. group blocks move plan by the destination tier.
Map<String, Set<BlockTransferInfo>> blocksGroupedByDestTier = new HashMap<>();
for (BlockTransferInfo entry : plan.toMove()) {
String alias = entry.getDstLocation().tierAlias();
if (!blocksGroupedByDestTier.containsKey(alias)) {
blocksGroupedByDestTier.put(alias, new HashSet<BlockTransferInfo>());
}
blocksGroupedByDestTier.get(alias).add(entry);
}
// 2.2. move blocks in the order of their dst tiers, from bottom to top
for (int tierOrdinal = mStorageTierAssoc.size() - 1; tierOrdinal >= 0; --tierOrdinal) {
Set<BlockTransferInfo> toMove = blocksGroupedByDestTier.get(mStorageTierAssoc.getAlias(tierOrdinal));
if (toMove == null) {
toMove = new HashSet<>();
}
for (BlockTransferInfo entry : toMove) {
long blockId = entry.getBlockId();
BlockStoreLocation oldLocation = entry.getSrcLocation();
BlockStoreLocation newLocation = entry.getDstLocation();
MoveBlockResult moveResult;
try {
moveResult = moveBlockInternal(sessionId, blockId, oldLocation, newLocation);
} catch (InvalidWorkerStateException e) {
// Evictor is not working properly
LOG.error("Failed to evict blockId {}, this is temp block", blockId);
continue;
} catch (BlockAlreadyExistsException e) {
continue;
} catch (BlockDoesNotExistException e) {
LOG.info("Failed to move blockId {}, it could be already deleted", blockId);
continue;
}
if (moveResult.getSuccess()) {
synchronized (mBlockStoreEventListeners) {
for (BlockStoreEventListener listener : mBlockStoreEventListeners) {
listener.onMoveBlockByWorker(sessionId, blockId, moveResult.getSrcLocation(), newLocation);
}
}
}
}
}
}
use of alluxio.resource.LockResource in project alluxio by Alluxio.
the class TieredBlockStore method commitBlockInternal.
/**
* Commits a temp block.
*
* @param sessionId the id of session
* @param blockId the id of block
* @return destination location to move the block
* @throws BlockDoesNotExistException if block id can not be found in temporary blocks
* @throws BlockAlreadyExistsException if block id already exists in committed blocks
* @throws InvalidWorkerStateException if block id is not owned by session id
* @throws IOException if I/O errors occur when deleting the block file
*/
private BlockStoreLocation commitBlockInternal(long sessionId, long blockId) throws BlockAlreadyExistsException, InvalidWorkerStateException, BlockDoesNotExistException, IOException {
long lockId = mLockManager.lockBlock(sessionId, blockId, BlockLockType.WRITE);
try {
// When committing TempBlockMeta, the final BlockMeta calculates the block size according to
// the actual file size of this TempBlockMeta. Therefore, commitTempBlockMeta must happen
// after moving actual block file to its committed path.
BlockStoreLocation loc;
String srcPath;
String dstPath;
TempBlockMeta tempBlockMeta;
try (LockResource r = new LockResource(mMetadataReadLock)) {
checkTempBlockOwnedBySession(sessionId, blockId);
tempBlockMeta = mMetaManager.getTempBlockMeta(blockId);
srcPath = tempBlockMeta.getPath();
dstPath = tempBlockMeta.getCommitPath();
loc = tempBlockMeta.getBlockLocation();
}
// Heavy IO is guarded by block lock but not metadata lock. This may throw IOException.
FileUtils.move(srcPath, dstPath);
try (LockResource r = new LockResource(mMetadataWriteLock)) {
mMetaManager.commitTempBlockMeta(tempBlockMeta);
} catch (BlockAlreadyExistsException | BlockDoesNotExistException | WorkerOutOfSpaceException e) {
// we shall never reach here
throw Throwables.propagate(e);
}
return loc;
} finally {
mLockManager.unlockBlock(lockId);
}
}
Aggregations