use of alluxio.security.authorization.Mode in project alluxio by Alluxio.
the class FileSystemMaster method loadFileMetadataAndJournal.
/**
* Loads metadata for the file identified by the given path from UFS into Alluxio.
*
* @param inodePath the path for which metadata should be loaded
* @param resolution the UFS resolution of path
* @param options the load metadata options
* @param journalContext the journal context
* @throws BlockInfoException if an invalid block size is encountered
* @throws FileDoesNotExistException if there is no UFS path
* @throws InvalidPathException if invalid path is encountered
* @throws AccessControlException if permission checking fails or permission setting fails
* @throws FileAlreadyCompletedException if the file is already completed
* @throws InvalidFileSizeException if invalid file size is encountered
* @throws IOException if an I/O error occurs
*/
private void loadFileMetadataAndJournal(LockedInodePath inodePath, MountTable.Resolution resolution, LoadMetadataOptions options, JournalContext journalContext) throws BlockInfoException, FileDoesNotExistException, InvalidPathException, AccessControlException, FileAlreadyCompletedException, InvalidFileSizeException, IOException {
if (inodePath.fullPathExists()) {
return;
}
AlluxioURI ufsUri = resolution.getUri();
UnderFileSystem ufs = resolution.getUfs();
long ufsBlockSizeByte = ufs.getBlockSizeByte(ufsUri.toString());
long ufsLength = ufs.getFileSize(ufsUri.toString());
// Metadata loaded from UFS has no TTL set.
CreateFileOptions createFileOptions = CreateFileOptions.defaults().setBlockSizeBytes(ufsBlockSizeByte).setRecursive(options.isCreateAncestors()).setMetadataLoad(true).setPersisted(true);
String ufsOwner = ufs.getOwner(ufsUri.toString());
String ufsGroup = ufs.getGroup(ufsUri.toString());
short ufsMode = ufs.getMode(ufsUri.toString());
Mode mode = new Mode(ufsMode);
if (resolution.getShared()) {
mode.setOtherBits(mode.getOtherBits().or(mode.getOwnerBits()));
}
createFileOptions = createFileOptions.setOwner(ufsOwner).setGroup(ufsGroup).setMode(mode);
try {
createFileAndJournal(inodePath, createFileOptions, journalContext);
CompleteFileOptions completeOptions = CompleteFileOptions.defaults().setUfsLength(ufsLength);
completeFileAndJournal(inodePath, completeOptions, journalContext);
} catch (FileAlreadyExistsException e) {
LOG.error("FileAlreadyExistsException seen unexpectedly.", e);
throw new RuntimeException(e);
}
}
use of alluxio.security.authorization.Mode in project alluxio by Alluxio.
the class FileSystemMaster method loadDirectoryMetadataAndJournal.
/**
* Loads metadata for the directory identified by the given path from UFS into Alluxio. This does
* not actually require looking at the UFS path.
* It is a no-op if the directory exists and is persisted.
*
* @param inodePath the path for which metadata should be loaded
* @param options the load metadata options
* @param journalContext the journal context
* @throws InvalidPathException if invalid path is encountered
* @throws IOException if an I/O error occurs
* @throws AccessControlException if permission checking fails
* @throws FileDoesNotExistException if the path does not exist
*/
private void loadDirectoryMetadataAndJournal(LockedInodePath inodePath, LoadMetadataOptions options, JournalContext journalContext) throws FileDoesNotExistException, InvalidPathException, AccessControlException, IOException {
if (inodePath.fullPathExists()) {
if (inodePath.getInode().isPersisted()) {
return;
}
}
CreateDirectoryOptions createDirectoryOptions = CreateDirectoryOptions.defaults().setMountPoint(mMountTable.isMountPoint(inodePath.getUri())).setPersisted(true).setRecursive(options.isCreateAncestors()).setMetadataLoad(true).setAllowExists(true);
MountTable.Resolution resolution = mMountTable.resolve(inodePath.getUri());
AlluxioURI ufsUri = resolution.getUri();
UnderFileSystem ufs = resolution.getUfs();
String ufsOwner = ufs.getOwner(ufsUri.toString());
String ufsGroup = ufs.getGroup(ufsUri.toString());
short ufsMode = ufs.getMode(ufsUri.toString());
Mode mode = new Mode(ufsMode);
if (resolution.getShared()) {
mode.setOtherBits(mode.getOtherBits().or(mode.getOwnerBits()));
}
createDirectoryOptions = createDirectoryOptions.setOwner(ufsOwner).setGroup(ufsGroup).setMode(mode);
try {
createDirectoryAndJournal(inodePath, createDirectoryOptions, journalContext);
} catch (FileAlreadyExistsException e) {
// This should not happen.
throw new RuntimeException(e);
}
}
use of alluxio.security.authorization.Mode in project alluxio by Alluxio.
the class FileSystemMaster method renameInternal.
/**
* Implements renaming.
*
* @param srcInodePath the path of the rename source
* @param dstInodePath the path to the rename destination
* @param replayed whether the operation is a result of replaying the journal
* @param options method options
* @throws FileDoesNotExistException if a non-existent file is encountered
* @throws InvalidPathException if an invalid path is encountered
* @throws IOException if an I/O error is encountered
*/
private void renameInternal(LockedInodePath srcInodePath, LockedInodePath dstInodePath, boolean replayed, RenameOptions options) throws FileDoesNotExistException, InvalidPathException, IOException {
// Rename logic:
// 1. Change the source inode name to the destination name.
// 2. Insert the source inode into the destination parent.
// 3. Do UFS operations if necessary.
// 4. Remove the source inode (reverting the name) from the source parent.
// 5. Set the last modification times for both source and destination parent inodes.
Inode<?> srcInode = srcInodePath.getInode();
AlluxioURI srcPath = srcInodePath.getUri();
AlluxioURI dstPath = dstInodePath.getUri();
InodeDirectory srcParentInode = srcInodePath.getParentInodeDirectory();
InodeDirectory dstParentInode = dstInodePath.getParentInodeDirectory();
String srcName = srcPath.getName();
String dstName = dstPath.getName();
LOG.debug("Renaming {} to {}", srcPath, dstPath);
// 1. Change the source inode name to the destination name.
srcInode.setName(dstName);
srcInode.setParentId(dstParentInode.getId());
// 2. Insert the source inode into the destination parent.
if (!dstParentInode.addChild(srcInode)) {
// On failure, revert changes and throw exception.
srcInode.setName(srcName);
srcInode.setParentId(srcParentInode.getId());
throw new InvalidPathException("Destination path: " + dstPath + " already exists.");
}
// If the source file is persisted, rename it in the UFS.
try {
if (!replayed && srcInode.isPersisted()) {
MountTable.Resolution resolution = mMountTable.resolve(srcPath);
String ufsSrcPath = resolution.getUri().toString();
UnderFileSystem ufs = resolution.getUfs();
String ufsDstUri = mMountTable.resolve(dstPath).getUri().toString();
// Create ancestor directories from top to the bottom. We cannot use recursive create
// parents here because the permission for the ancestors can be different.
List<Inode<?>> dstInodeList = dstInodePath.getInodeList();
Stack<Pair<String, MkdirsOptions>> ufsDirsToMakeWithOptions = new Stack<>();
AlluxioURI curUfsDirPath = new AlluxioURI(ufsDstUri).getParent();
// The dst inode does not exist yet, so the last inode in the list is the existing parent.
for (int i = dstInodeList.size() - 1; i >= 0; i--) {
if (ufs.isDirectory(curUfsDirPath.toString())) {
break;
}
Inode<?> curInode = dstInodeList.get(i);
MkdirsOptions mkdirsOptions = MkdirsOptions.defaults().setCreateParent(false).setOwner(curInode.getOwner()).setGroup(curInode.getGroup()).setMode(new Mode(curInode.getMode()));
ufsDirsToMakeWithOptions.push(new Pair<>(curUfsDirPath.toString(), mkdirsOptions));
curUfsDirPath = curUfsDirPath.getParent();
}
while (!ufsDirsToMakeWithOptions.empty()) {
Pair<String, MkdirsOptions> ufsDirAndPerm = ufsDirsToMakeWithOptions.pop();
if (!ufs.mkdirs(ufsDirAndPerm.getFirst(), ufsDirAndPerm.getSecond())) {
throw new IOException(ExceptionMessage.FAILED_UFS_CREATE.getMessage(ufsDirAndPerm.getFirst()));
}
}
boolean success;
if (srcInode.isFile()) {
success = ufs.renameFile(ufsSrcPath, ufsDstUri);
} else {
success = ufs.renameDirectory(ufsSrcPath, ufsDstUri);
}
if (!success) {
throw new IOException(ExceptionMessage.FAILED_UFS_RENAME.getMessage(ufsSrcPath, ufsDstUri));
}
}
} catch (Exception e) {
// On failure, revert changes and throw exception.
if (!dstParentInode.removeChild(dstName)) {
LOG.error("Failed to revert rename changes. Alluxio metadata may be inconsistent.");
}
srcInode.setName(srcName);
srcInode.setParentId(srcParentInode.getId());
throw e;
}
// TODO(jiri): A crash between now and the time the rename operation is journaled will result in
// an inconsistency between Alluxio and UFS.
// 4. Remove the source inode (reverting the name) from the source parent. The name must be
// reverted or removeChild will not be able to find the appropriate child entry since it is
// keyed on the original name.
srcInode.setName(srcName);
if (!srcParentInode.removeChild(srcInode)) {
// This should never happen.
LOG.error("Failed to rename {} to {} in Alluxio. Alluxio and under storage may be " + "inconsistent.", srcPath, dstPath);
srcInode.setName(dstName);
if (!dstParentInode.removeChild(dstName)) {
LOG.error("Failed to revert changes when renaming {} to {}. Alluxio metadata may be " + "inconsistent.", srcPath, dstPath);
}
srcInode.setName(srcName);
srcInode.setParentId(srcParentInode.getId());
throw new IOException("Failed to remove source path " + srcPath + " from parent");
}
srcInode.setName(dstName);
// 5. Set the last modification times for both source and destination parent inodes.
// Note this step relies on setLastModificationTimeMs being thread safe to guarantee the
// correct behavior when multiple files are being renamed within a directory.
dstParentInode.setLastModificationTimeMs(options.getOperationTimeMs());
srcParentInode.setLastModificationTimeMs(options.getOperationTimeMs());
Metrics.PATHS_RENAMED.inc();
}
use of alluxio.security.authorization.Mode in project alluxio by Alluxio.
the class JournalIntegrationTest method setAcl.
@Test
@LocalAlluxioClusterResource.Config(confParams = { PropertyKey.Name.SECURITY_AUTHENTICATION_TYPE, "SIMPLE", PropertyKey.Name.SECURITY_AUTHORIZATION_PERMISSION_ENABLED, "true", PropertyKey.Name.SECURITY_GROUP_MAPPING_CLASS, FakeUserGroupsMapping.FULL_CLASS_NAME })
public void setAcl() throws Exception {
AlluxioURI filePath = new AlluxioURI("/file");
String user = "alluxio";
Configuration.set(PropertyKey.SECURITY_LOGIN_USERNAME, user);
CreateFileOptions op = CreateFileOptions.defaults().setBlockSizeBytes(64);
mFileSystem.createFile(filePath, op).close();
// TODO(chaomin): also setOwner and setGroup once there's a way to fake the owner/group in UFS.
mFileSystem.setAttribute(filePath, SetAttributeOptions.defaults().setMode(new Mode((short) 0400)).setRecursive(false));
URIStatus status = mFileSystem.getStatus(filePath);
mLocalAlluxioCluster.stopFS();
aclTestUtil(status, user);
deleteFsMasterJournalLogs();
aclTestUtil(status, user);
}
use of alluxio.security.authorization.Mode in project alluxio by Alluxio.
the class FileSystemAclIntegrationTest method loadDirMetadataMode.
/**
* Tests the loaded directory metadata from UFS having the same mode as that in the UFS.
*/
@Test
public void loadDirMetadataMode() throws Exception {
// Skip non-local and non-HDFS UFSs.
Assume.assumeTrue(UnderFileSystemUtils.isLocal(sUfs) || UnderFileSystemUtils.isHdfs(sUfs));
List<Integer> permissionValues = Lists.newArrayList(0111, 0222, 0333, 0444, 0555, 0666, 0777, 0755, 0733, 0644, 0533, 0511);
for (int value : permissionValues) {
Path dir = new Path("/loadDirMetadataMode" + value + "/");
sTFS.delete(dir, true);
// Create a directory directly in UFS and set the corresponding mode.
String ufsPath = PathUtils.concatPath(sUfsRoot, dir);
sUfs.mkdirs(ufsPath, MkdirsOptions.defaults().setCreateParent(false).setOwner("testuser").setGroup("testgroup").setMode(new Mode((short) value)));
Assert.assertTrue(sUfs.isDirectory(PathUtils.concatPath(sUfsRoot, dir)));
// Check the mode is consistent in Alluxio namespace once it's loaded from UFS to Alluxio.
Assert.assertEquals(new Mode((short) value).toString(), new Mode(sTFS.getFileStatus(dir).getPermission().toShort()).toString());
}
}
Aggregations