Skip to content

Commit

Permalink
Merge pull request #13 from jayunit100/master
Browse files Browse the repository at this point in the history
Fixes for Permissions and Secuirty Exceptions  [MERGE]
  • Loading branch information
jayunit100 committed Mar 25, 2013
2 parents 9b24072 + 38a220d commit f7162f1
Show file tree
Hide file tree
Showing 5 changed files with 328 additions and 63 deletions.
1 change: 0 additions & 1 deletion README
Expand Up @@ -44,7 +44,6 @@ INSTALLATION

# ls target/
classes glusterfs-0.20.2-0.1.jar maven-archiver surefire-reports test-classes
^^^^^^^^^^^^^^^^^^

Copy the plugin to lib/ directory in your $HADOOP_HOME dir.

Expand Down
78 changes: 78 additions & 0 deletions src/main/java/org/apache/hadoop/fs/glusterfs/FileInfoUtil.java
@@ -0,0 +1,78 @@
package org.apache.hadoop.fs.glusterfs;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;

/**
* Because java 6 doesn't support cross platform file info, we use Runtime exec
* to get details.
*
* This class will be extended in the future to also return permissions.
*/
public class FileInfoUtil {

/**
* Returns the array of values from ls -aFl :
*
* Currently only handles "owner" , since that is what is most needed by
* the GFAPI that is meant to use this class.
*
* m = getLSinfo("myfile.txt").get("owner")
* System.out.println(m) ; <-- jayunit100
*/
public static Map<String, String> getLSinfo(String filename) throws IOException {
String ret="";
try {
String ls_str;
Process ls_proc = Runtime.getRuntime().exec("/bin/ls -aFl " + filename);
DataInputStream ls_in = new DataInputStream(
ls_proc.getInputStream());
try {
//should only be one line if input is a file
while ((ls_str = ls_in.readLine()) != null) {
if(ls_str.length()<10)
;
else{
ret+=(ls_str);
}
}
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
catch (IOException e1) {
throw new RuntimeException(e1);
}
//initialization to "" was only to make for clean appending.
if(ret.equals(""))
ret=null;

//Convenience: transform to map
Map<String, String> mm = lsToMap(ret);
return mm;
}

/**
* Converts the output of ls -aFl to a map :
*
* EXPECTED INPUT STRING:
* -rwxr-xr-x. 1 root root 786 Mar 7 11:42 buildbranch_and_copyjartovms.sh*
*
* EXPECTED OUTPUT:
* key="owner" -> the owner of the file (root)
* key="permissions" -> the hadoop permissions on the file.
*/
private static Map<String, String> lsToMap(String ret) {
String[] values = ret.split("\\s+");

Map<String,String> mm = new TreeMap();
mm.put("owner", values[2]);

return mm;
}


}
205 changes: 160 additions & 45 deletions src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFileSystem.java
Expand Up @@ -21,12 +21,13 @@
* Implements the Hadoop FileSystem Interface to allow applications to store
* files on GlusterFS and run Map/Reduce jobs on the data.
*/

package org.apache.hadoop.fs.glusterfs;

import java.io.*;
import java.net.*;

import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.regex.*;

import org.apache.hadoop.conf.Configuration;
Expand All @@ -39,8 +40,8 @@
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.util.Progressable;

import java.util.TreeMap;
import org.apache.hadoop.util.Shell;
import org.apache.hadoop.util.StringUtils;

/*
* This package provides interface for hadoop jobs (incl. Map/Reduce)
Expand Down Expand Up @@ -83,23 +84,22 @@ public boolean FUSEMount(String volname, String server, String mount)
boolean ret = true;
int retVal = 0;
Process p = null;
String s = null;
String mountCmd = null;

mountCmd = "mount -t glusterfs " + server + ":" + "/" + volname + " "+ mount;
System.out.println("Running: " + mountCmd);
mountCmd = "mount -t glusterfs " + server + ":" + "/" + volname + " "
+ mount;
System.out.println(mountCmd);
try {
p = Runtime.getRuntime().exec(mountCmd);

retVal = p.waitFor();
if (retVal != 0)
ret = false;
}
catch (IOException e) {
e.printStackTrace();
System.out.println("Error calling mount, Continuing.., hopefully its already been mounted.");
//throw new RuntimeException("Problem mounting FUSE mount on: "+ mount);
System.out.println("Problem mounting FUSE mount on: " + mount);
throw new RuntimeException(e);
}

return ret;
}

Expand All @@ -122,20 +122,29 @@ public void initialize(URI uri, Configuration conf) throws IOException {
needQuickRead = conf.get("quick.slave.io", null);
autoMount = conf.getBoolean("fs.glusterfs.automount", true);

/*
* bail out if we do not have enough information to do a FUSE mount
*/
if ((volName.length() == 0) || (remoteGFSServer.length() == 0)
|| (glusterMount.length() == 0))
throw new RuntimeException("Not enough info to mount FUSE: volname="+volName + " glustermount=" + glusterMount);


if (autoMount) {
ret = FUSEMount(volName, remoteGFSServer, glusterMount);
if (!ret) {
throw new RuntimeException("Initialize: Failed to mount GlusterFS ");
}
}

if((needQuickRead.length() != 0)
&& (needQuickRead.equalsIgnoreCase("yes")
throw new RuntimeException(
"Not enough info for FUSE Mount : volname=" + volName
+ ",server=" + remoteGFSServer
+ ",glustermount=" + glusterMount);

ret = FUSEMount(volName, remoteGFSServer, glusterMount);

if (!ret) {
throw new RuntimeException("Failed to init Gluster FS");
}
if (autoMount) {
ret = FUSEMount(volName, remoteGFSServer, glusterMount);
if (!ret) {
throw new RuntimeException("Initialize: Failed to mount GlusterFS ");
}
}
if((needQuickRead.length() != 0)
&& (needQuickRead.equalsIgnoreCase("yes")
|| needQuickRead.equalsIgnoreCase("on") || needQuickRead
.equals("1")))
this.quickSlaveIO = true;
Expand All @@ -153,8 +162,7 @@ public void initialize(URI uri, Configuration conf) throws IOException {
setConf(conf);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Unable to initialize GlusterFS " + e.getMessage());
throw new RuntimeException(e);
}
}

Expand Down Expand Up @@ -199,13 +207,14 @@ public boolean exists(Path path) throws IOException {
*/
public boolean mkdirs(Path f, FsPermission permission) throws IOException {

if(f==null) return true;

Path parent = f.getParent();
Path absolute = makeAbsolute(f);
File p2f = new File(absolute.toUri().getPath());
return (f == null || mkdirs(parent)) && (p2f.mkdir() || p2f.isDirectory());
}
if(f==null)
return true;

Path parent = f.getParent();
Path absolute = makeAbsolute(f);
File p2f = new File(absolute.toUri().getPath());
return (f == null || mkdirs(parent)) && (p2f.mkdir() || p2f.isDirectory());
}

@Deprecated
public boolean isDirectory(Path path) throws IOException {
Expand Down Expand Up @@ -274,31 +283,137 @@ public FileStatus getFileStatusFromFileString(String path)
return getFileStatus(nPath);
}

public static class FUSEFileStatus extends FileStatus {
File theFile;

public FUSEFileStatus(File f) {
super();
theFile = f;
}

public FUSEFileStatus(File f, boolean isdir, int block_replication,
long blocksize, Path path) {
// if its a dir, 0 length
super(isdir ? 0 : f.length(), isdir, block_replication, blocksize,
f.lastModified(), path);
theFile = f;
}

/**
* Wrapper to "ls -aFL" - this should fix BZ908898
*/
@Override
public String getOwner() {
try {
return FileInfoUtil.getLSinfo(theFile.getAbsolutePath()).
get("owner");
}
catch (Exception e) {
throw new RuntimeException(e);
}
}

public FsPermission getPermission() {
//should be amortized, see method.
loadPermissionInfo();
return super.getPermission();
}

boolean permsLoaded=false;

/// loads permissions, owner, and group from `ls -ld`
private void loadPermissionInfo() {
if (permsLoaded) {
return;
}
IOException e = null;
try {
String output;
StringTokenizer t = new StringTokenizer(
output=execCommand(theFile,
Shell.getGET_PERMISSION_COMMAND()));

//System.out.println("Output of PERMISSION command = " + output + " for " + this.getPath());
//expected format
//-rw------- 1 username groupname ...
String permission = t.nextToken();
if (permission.length() > 10) { //files with ACLs might have a '+'
permission = permission.substring(0, 10);
}
setPermission(FsPermission.valueOf(permission));
t.nextToken();
setOwner(t.nextToken());
setGroup(t.nextToken());
} catch (Shell.ExitCodeException ioe) {
if (ioe.getExitCode() != 1) {
e = ioe;
} else {
setPermission(null);
setOwner(null);
setGroup(null);
}
permsLoaded=true;
}
catch (IOException ioe) {
e = ioe;
}
finally {
if (e != null) {
throw new RuntimeException("Error while running command to get " +
"file permissions : " +
StringUtils.stringifyException(e));
}
}
}

}

public static String execCommand(File f, String... cmd) throws IOException {
String[] args = new String[cmd.length + 1];
System.arraycopy(cmd, 0, args, 0, cmd.length);
args[cmd.length] = f.getCanonicalPath();
String output = Shell.execCommand(args);
return output;
}

/**
* We ultimately use chmod to set permissions, same as in
* https://svn.apache.org/repos/asf/hadoop/common/branches/HADOOP-3628/src/core/org/apache/hadoop/fs/RawLocalFileSystem.java
*/
@Override
public void setPermission(Path p, FsPermission permission){
try{
Path absolute = makeAbsolute(p);
final File f = new File(absolute.toUri().getPath());

execCommand(f, Shell.SET_PERMISSION_COMMAND,
String.format("%05o", permission.toShort()));
}
catch(Exception e){
throw new RuntimeException(e);
}
}


public FileStatus getFileStatus(Path path) throws IOException {
Path absolute = makeAbsolute(path);
File f = new File(absolute.toUri().getPath());
final File f = new File(absolute.toUri().getPath());

if (!f.exists())
throw new FileNotFoundException("File " + f.getPath()
+ " does not exist.");

FileStatus fs;

// simple version - should work . we'll see.
// TODO COMPARE these w/ original signatures - do we retain the correct
// default args?
if (f.isDirectory())
fs = new FileStatus(0, true, 1, 0, f.lastModified(),
path.makeQualified(this)) {
public String getOwner() {
return "root";
}
};
fs = new FUSEFileStatus(f, true, 1, 0, path.makeQualified(this));
else
fs = new FileStatus(f.length(), false, 0, getDefaultBlockSize(),
f.lastModified(), path.makeQualified(this)) {
public String getOwner() {
return "root";
}
};
fs = new FUSEFileStatus(f, false, 0, getDefaultBlockSize(),
path.makeQualified(this));
return fs;

}

/*
Expand Down

0 comments on commit f7162f1

Please sign in to comment.