HDFS权限部分
一 绪论
就目前所学,HDFS在很多方面是依照Unix实现的,比如说对于文件/目录都抽象为INode类;对于文件目录的权限,也是仿照’rwxrwxrwx’进行划分,rwx为一组,分别为可读、可写、可执行,三组分别对应于当前用户、当前用户所在组、其他。
二 实现
1. FsAction
FsAction是一个枚举类,用于描述一组"rwx"的情况,需要啰嗦的是,不同权限点可以通过位运算实现,比如读权限(4) &写权限(2)=读写权限(6),同时,none(0) + all(0) = 7,execute(1) + read_write(6) = 7,又是互补的存在。
--- none 0 000
--x execute 1 001
-w- write 2 010
-wx write_execute 3 011
r-- read 4 100
r-x read_exectue 5 101
rw- read_write 6 110
rwx all 7 111
public enum FsAction {
NONE("---"),
EXECUTE("--x"),
WRITE("-w-"),
WRITE_EXECUTE("-wx"),
READ("r--"),
READ_EXECUTE("r-x"),
READ_WRITE("rw-"),
ALL("rwx");
private final static FsAction[] vals = values();
private final String SYMBOL;
private FsAction(String s){
SYMBOL = s;
}
/**
形参that的权限点是否为本FsAction对象权限点的子集
**/
public boolean implies(FsAction that){
if(that != null){
return (ordinal() & that.ordinal()) == that.ordinal();
}
return false;
}
public FsAction and(FsAction that){
return vals[ordinal() & that.ordinal()];
}
public FsAction or(FsAction that){
return vals[ordinal() | that.ordinal()];
}
public FsAction not(){
return vals[7 - ordinal()];
}
public static FsAction getFsAction(String permission){
for(FsAction fsAction : vals){
if(fsAction.SYMBOL.equals(permission)){
return fsAction;
}
}
return null;
}
}
2. FsPermission
FsPermission用来描述一个INode(文件/目录)的权限信息,共包括三组,分别是当前用户、当前用户所属组内成员、其他。
我们知道,FsAction用来表示一组权限点,可以用0-7,3个比特位进行表示,那么三组的话可以用9比特进行表示,再加上stickyBit,共10比特。INode的权限点是要进行持久化存储,即需要存到磁盘上中的FSImage中的,同时内存中也会存储INode的权限信息,那么为了节省存储空间,没必要对String或是FsPermission对象进行存储,只需要通过一个short(16位)类型存储, 在计算时进行转换即可。
public class FsPermission implements Writable {
//"rwxrwxrwx"长度为9,还有一个可选项stickyBit,最多为10
public static final int MAX_PERMISSION_LENGTH = 10;
private FsAction useraction = null;
private FsAction groupaction = null;
private FsAction otheraction = null;
private boolean stickyBit = false;
private static final FsAction[] FSACTION_VALUES = FsAction.values();
private FsAction(){
//do nothing;
}
public FsPermission(FsActioni u, FsAction g, FsAction o){
this(u, g, o, false);
}
public FsPermission(FsAction u, FsAction g, FsAction o, boolean stickyBit){
set(u, g, o, sb);
}
public FsPermission(short mode){
fromShort(mode);
}
public FsPermission(FsPermission other){
this.useraction = other.useraction;
this.groupaction = other.groupaction;
this.otheraction = other.otheraction;
this.stickyBit = other.other.stickyBit;
}
public FsAction getUserAction(){
return userAction;
}
public FsAction getGroupAction(){
return groupAction;
}
public FsAction getOtherAction(){
return otherAction;
}
private void set(FsAction u, FsAction g, FsAction o, boolean sb){
useraction = u;
groupaction = g;
otheraction = o;
stickyBit = sb;
}
public void fromShort(short n){
FsAction[] v = FSACTION_VALUES;
set(v[n >>> 6] & 7, v[n >>> 3] & 7, v[n & 7], (((n >>>9) & 1) == 1));
}
public short toShort(){
int s = (stickyBit ? 1 << 9 : 0) |
(useraction.ordinal() << 6) |
(groupaction.oridnal() << 3) |
otheraction.ordinal();
return (short)s;
}
@Override
public void write(DataOutput out) throws IOException{
out.writeShort(toShort());
}
@Override
public void readFields(DataInput in) throws IOException{
fromShort(in.readShort());
}
/**
实际上就是读取DataInput输入流,构建FsPermission对象
**/
public static FsPermission read(DataInput in) throws IOException{
FsPermission p = new FsPermission();
p.readFields(in);
return p;
}
//Umask相关就不再赘述,可自行查看Linux umask以及该部分源码
}