use of alluxio.master.file.contexts.SetAttributeContext in project alluxio by Alluxio.
the class InodeSyncStream method syncExistingInodeMetadata.
/**
* Sync inode metadata with the UFS state.
*
* This method expects the {@code inodePath} to already exist in the inode tree.
*/
private void syncExistingInodeMetadata(LockedInodePath inodePath, boolean skipLoad) throws AccessControlException, BlockInfoException, FileAlreadyCompletedException, FileDoesNotExistException, InvalidFileSizeException, InvalidPathException, IOException, InterruptedException {
if (inodePath.getLockPattern() != LockPattern.WRITE_EDGE && !mLoadOnly) {
throw new RuntimeException(String.format("syncExistingInodeMetadata was called on d%s when only locked with %s. Load metadata" + " only was not specified.", inodePath.getUri(), inodePath.getLockPattern()));
}
// Set to true if the given inode was deleted.
boolean deletedInode = false;
// whether we need to load metadata for the current path
boolean loadMetadata = mLoadOnly;
LOG.trace("Syncing inode metadata {}", inodePath.getUri());
// The requested path already exists in Alluxio.
Inode inode = inodePath.getInode();
// initialize sync children to true if it is a listStatus call on a directory
boolean syncChildren = inode.isDirectory() && !mIsGetFileInfo && !mDescendantType.equals(DescendantType.NONE);
if (inodePath.getLockPattern() == LockPattern.WRITE_EDGE && !mLoadOnly) {
if (inode instanceof InodeFile && !inode.asFile().isCompleted()) {
// Do not sync an incomplete file, since the UFS file is expected to not exist.
return;
}
Optional<Scoped> persistingLock = mInodeLockManager.tryAcquirePersistingLock(inode.getId());
if (!persistingLock.isPresent()) {
// written.
return;
}
persistingLock.get().close();
UfsStatus cachedStatus = null;
boolean fileNotFound = false;
try {
cachedStatus = mStatusCache.getStatus(inodePath.getUri());
} catch (FileNotFoundException e) {
fileNotFound = true;
}
MountTable.Resolution resolution = mMountTable.resolve(inodePath.getUri());
AlluxioURI ufsUri = resolution.getUri();
try (CloseableResource<UnderFileSystem> ufsResource = resolution.acquireUfsResource()) {
UnderFileSystem ufs = ufsResource.get();
String ufsFingerprint;
Fingerprint ufsFpParsed;
// When the status is not cached and it was not due to file not found, we retry
if (fileNotFound) {
ufsFingerprint = Constants.INVALID_UFS_FINGERPRINT;
ufsFpParsed = Fingerprint.parse(ufsFingerprint);
} else if (cachedStatus == null) {
// TODO(david): change the interface so that getFingerprint returns a parsed fingerprint
ufsFingerprint = (String) getFromUfs(() -> ufs.getFingerprint(ufsUri.toString()));
ufsFpParsed = Fingerprint.parse(ufsFingerprint);
} else {
// When the status is cached
Pair<AccessControlList, DefaultAccessControlList> aclPair = (Pair<AccessControlList, DefaultAccessControlList>) getFromUfs(() -> ufs.getAclPair(ufsUri.toString()));
if (aclPair == null || aclPair.getFirst() == null || !aclPair.getFirst().hasExtended()) {
ufsFpParsed = Fingerprint.create(ufs.getUnderFSType(), cachedStatus);
} else {
ufsFpParsed = Fingerprint.create(ufs.getUnderFSType(), cachedStatus, aclPair.getFirst());
}
ufsFingerprint = ufsFpParsed.serialize();
}
boolean containsMountPoint = mMountTable.containsMountPoint(inodePath.getUri(), true);
UfsSyncUtils.SyncPlan syncPlan = UfsSyncUtils.computeSyncPlan(inode, ufsFpParsed, containsMountPoint);
if (syncPlan.toUpdateMetaData()) {
// It works by calling SetAttributeInternal on the inodePath.
if (ufsFpParsed != null && ufsFpParsed.isValid()) {
short mode = Short.parseShort(ufsFpParsed.getTag(Fingerprint.Tag.MODE));
long opTimeMs = System.currentTimeMillis();
SetAttributePOptions.Builder builder = SetAttributePOptions.newBuilder().setMode(new Mode(mode).toProto());
String owner = ufsFpParsed.getTag(Fingerprint.Tag.OWNER);
if (!owner.equals(Fingerprint.UNDERSCORE)) {
// Only set owner if not empty
builder.setOwner(owner);
}
String group = ufsFpParsed.getTag(Fingerprint.Tag.GROUP);
if (!group.equals(Fingerprint.UNDERSCORE)) {
// Only set group if not empty
builder.setGroup(group);
}
SetAttributeContext ctx = SetAttributeContext.mergeFrom(builder).setUfsFingerprint(ufsFingerprint);
mFsMaster.setAttributeSingleFile(mRpcContext, inodePath, false, opTimeMs, ctx);
}
}
if (syncPlan.toDelete()) {
deletedInode = true;
try {
// The options for deleting.
DeleteContext syncDeleteContext = DeleteContext.mergeFrom(DeletePOptions.newBuilder().setRecursive(true).setAlluxioOnly(true).setUnchecked(true));
mFsMaster.deleteInternal(mRpcContext, inodePath, syncDeleteContext);
} catch (DirectoryNotEmptyException | IOException e) {
// Should not happen, since it is an unchecked delete.
LOG.error("Unexpected error for unchecked delete.", e);
}
}
if (syncPlan.toLoadMetadata()) {
loadMetadata = true;
}
syncChildren = syncPlan.toSyncChildren();
}
}
// if DescendantType.ONE we only sync children if we are syncing root of this stream
if (mDescendantType == DescendantType.ONE) {
syncChildren = syncChildren && mRootScheme.getPath().equals(inodePath.getUri());
}
Map<String, Inode> inodeChildren = new HashMap<>();
if (syncChildren) {
// maps children name to inode
mInodeStore.getChildren(inode.asDirectory()).forEach(child -> inodeChildren.put(child.getName(), child));
// Fetch and populate children into the cache
mStatusCache.prefetchChildren(inodePath.getUri(), mMountTable);
Collection<UfsStatus> listStatus = mStatusCache.fetchChildrenIfAbsent(mRpcContext, inodePath.getUri(), mMountTable);
// Iterate over UFS listings and process UFS children.
if (listStatus != null) {
for (UfsStatus ufsChildStatus : listStatus) {
if (!inodeChildren.containsKey(ufsChildStatus.getName()) && !PathUtils.isTemporaryFileName(ufsChildStatus.getName())) {
// Ufs child exists, but Alluxio child does not. Must load metadata.
loadMetadata = true;
break;
}
}
}
}
// locked path
if (deletedInode) {
inodePath.removeLastInode();
}
// load metadata if necessary.
if (loadMetadata && !skipLoad) {
loadMetadataForPath(inodePath);
}
if (syncChildren) {
// Iterate over Alluxio children and process persisted children.
mInodeStore.getChildren(inode.asDirectory()).forEach(childInode -> {
// its children.
if (mLoadOnly && inodeChildren.containsKey(childInode.getName()) && childInode.isFile()) {
return;
}
// If we're performing a recursive sync, add each child of our current Inode to the queue
AlluxioURI child = inodePath.getUri().joinUnsafe(childInode.getName());
mPendingPaths.add(child);
// This asynchronously schedules a job to pre-fetch the statuses into the cache.
if (childInode.isDirectory() && mDescendantType == DescendantType.ALL) {
mStatusCache.prefetchChildren(child, mMountTable);
}
});
}
}
use of alluxio.master.file.contexts.SetAttributeContext in project alluxio by Alluxio.
the class PermissionCheckTest method verifySetAcl.
private void verifySetAcl(TestUser runUser, String path, String owner, String group, short mode, boolean recursive) throws Exception {
try (Closeable r = new AuthenticatedUserRule(runUser.getUser(), ServerConfiguration.global()).toResource()) {
SetAttributeContext context = SetAttributeContext.mergeFrom(SetAttributePOptions.newBuilder().setMode(new Mode(mode).toProto()).setRecursive(recursive));
if (owner != null) {
context.getOptions().setOwner(owner);
}
if (group != null) {
context.getOptions().setGroup(group);
}
mFileSystemMaster.setAttribute(new AlluxioURI(path), context);
}
try (Closeable r = new AuthenticatedUserRule(TEST_USER_ADMIN.getUser(), ServerConfiguration.global()).toResource()) {
FileInfo fileInfo = mFileSystemMaster.getFileInfo(mFileSystemMaster.getFileId(new AlluxioURI(path)));
if (owner != null) {
assertEquals(owner, fileInfo.getOwner());
}
if (group != null) {
assertEquals(group, fileInfo.getGroup());
}
if (mode != -1) {
assertEquals(mode, fileInfo.getMode());
}
}
}
use of alluxio.master.file.contexts.SetAttributeContext in project alluxio by Alluxio.
the class DefaultFileSystemMaster method freeInternal.
/**
* Implements free operation.
*
* @param rpcContext the rpc context
* @param inodePath inode of the path to free
* @param context context to free method
*/
private void freeInternal(RpcContext rpcContext, LockedInodePath inodePath, FreeContext context) throws FileDoesNotExistException, UnexpectedAlluxioException, IOException, InvalidPathException, AccessControlException {
Inode inode = inodePath.getInode();
if (inode.isDirectory() && !context.getOptions().getRecursive() && mInodeStore.hasChildren(inode.asDirectory())) {
// inode is nonempty, and we don't free a nonempty directory unless recursive is true
throw new UnexpectedAlluxioException(ExceptionMessage.CANNOT_FREE_NON_EMPTY_DIR.getMessage(mInodeTree.getPath(inode)));
}
long opTimeMs = System.currentTimeMillis();
List<Inode> freeInodes = new ArrayList<>();
freeInodes.add(inode);
try (LockedInodePathList descendants = mInodeTree.getDescendants(inodePath)) {
for (LockedInodePath descedant : Iterables.concat(descendants, Collections.singleton(inodePath))) {
Inode freeInode = descedant.getInodeOrNull();
if (freeInode != null && freeInode.isFile()) {
if (freeInode.getPersistenceState() != PersistenceState.PERSISTED) {
throw new UnexpectedAlluxioException(ExceptionMessage.CANNOT_FREE_NON_PERSISTED_FILE.getMessage(mInodeTree.getPath(freeInode)));
}
if (freeInode.isPinned()) {
if (!context.getOptions().getForced()) {
throw new UnexpectedAlluxioException(ExceptionMessage.CANNOT_FREE_PINNED_FILE.getMessage(mInodeTree.getPath(freeInode)));
}
SetAttributeContext setAttributeContext = SetAttributeContext.mergeFrom(SetAttributePOptions.newBuilder().setRecursive(false).setPinned(false));
setAttributeSingleFile(rpcContext, descedant, true, opTimeMs, setAttributeContext);
}
// Remove corresponding blocks from workers.
mBlockMaster.removeBlocks(freeInode.asFile().getBlockIds(), false);
}
}
}
Metrics.FILES_FREED.inc(freeInodes.size());
}
Aggregations