En la primera parte de la introducción a los permisos en HDFS concluí que era más fácil utilizar IPFilter. La verdad es que esta conclusión la saqué después de mucho tiempo con la configuración a vueltas y un pequeño código que creaba unos archivos y luego los borraba.
El problema de DrWho
Después de un buen rato investigando el código de Hadoop, he encontrado el problema :D y creo que lo he solucionado.
El problema era muy sencillo, cuando ejecutaba un código muy simple que creaba n archivos desde Solaris, siempre me ponía como usuario "DrWho" y como group "" así que por muchos permisos que yo asignaba el código se los saltaba ya que DrWho es supergroup y por lo tanto no evalua los permisos.
Bien, el problema viene por cómo se mira quién es el usuario que está definido en la clase Shell.USER_NAME_COMMAND ($HADOOP_HOME/src/core/org/apache/hadoop/security/) que hace la llamada a "whoami", este comando no existe en Solaris así, sino "who am i", sin embargo, este comando no puede ser llamado si no estás atacado a la consola, así que estoy evaluando las siguientes opciones
- Modicar el path para incluir los binarios compatibles con BSD que se encuentran en /usr/ucb donde está whoami (Es necesario tener instalado el paquete SUNWscpu)
- Instalar whoami desde Sunfreeware.
- Crear un WhoAmI propio utilizando el comando id de Solaris. Esta solución que es la más complicada, es como no la que he seleccionado, ya que creo es más interesante.
# echo "/usr/xpg4/bin/id -un" > /usr/bin/whoamiCon este sencillo cambio, el sistema ya reconoce quien soy y por lo tanto evalúa los permisos correctamente. Por defecto los comando compatibles con BSD se encuentran en /usr/xpg4/, podíamos haber hecho un simple link para solucionar el problema, pero creo que es más correcto hacer que Hadoop se encargue de saber a que id llamar en función del OS.
# chmod +x /usr/bin/whoami
A continuación os muestro una ejecución sin el parche y otra con el parche
[java] hdfs://namenode.hadoop.test.com:54310/
[java] hdfs://namenode.hadoop.test.com:54311/
[java] Get UserName: hadoop
[java] Creating PATH 1248715418585
[java] Creating FILE 1248715418622
[java] Creating PATH 1248715421131
[java] 27-jul-2009 19:23:41 com.sfchildren.sbcore.backup.Main createTmpFile
[java] INFO: File testfile Created with Size: 1717833
[java] Creating FILE 1248715421148
[java] Creating PATH 1248715432033
[java] 27-jul-2009 19:23:52 com.sfchildren.sbcore.backup.Main createTmpFile
[java] INFO: File testfile Created with Size: 8968960
[java] Creating FILE 1248715432055
....
El log del NameNode
$ tail -f $HADOOP_HOME/log/hadoop--namenode*Y la estructura HDFS que tengo sólo permite la escritura al usuario hadoop de la siguiente forma
2009-07-27 19:19:00,082 INFO org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit: ugi=DrWho,postgres,dba ip=/10.80.1.82 cmd=create src=/user/DrWho/testdir/tres/testfile dst=null perm=DrWho:supergroup:rw-r--r--
$ hadoop fs -lsr /user/DrWhoSin embargo, después de ejecutar el comando (sin el parche) no sólo no falla, sino que se salta la seguridad por completo, aquí está el resultado
drwxr-xr-x - hadoop hadoop 0 2009-07-27 19:22 /user/DrWho/testdir
$ hadoop fs -lsr /user/DrWho
drwxr-xr-x - hadoop hadoop 0 2009-07-27 19:25 /user/DrWho/testdir
drwxr-xr-x - DrWho hadoop 0 2009-07-27 19:25 /user/DrWho/testdir/cuatro
-rw-r--r-- 3 DrWho hadoop 0 2009-07-27 19:25 /user/DrWho/testdir/cuatro/testfile
drwxr-xr-x - DrWho hadoop 0 2009-07-27 19:24 /user/DrWho/testdir/dos
-rw-r--r-- 3 DrWho hadoop 7731334 2009-07-27 19:24 /user/DrWho/testdir/dos/testfile
drwxr-xr-x - DrWho hadoop 0 2009-07-27 19:25 /user/DrWho/testdir/tres
-rw-r--r-- 3 DrWho hadoop 9384206 2009-07-27 19:25 /user/DrWho/testdir/tres/testfile
drwxr-xr-x - DrWho hadoop 0 2009-07-27 19:24 /user/DrWho/testdir/uno
-rw-r--r-- 3 DrWho hadoop 5752383 2009-07-27 19:24 /user/DrWho/testdir/uno/testfile
Sin embargo, si activo el parche el resultado es muy diferente
[java] hdfs://namenode.hadoop.test.com:54310/Conclusión
[java] hdfs://namenode.hadoop.test.com:54311/
[java] Get UserName: hadoop
[java] Result 0 Value: postgres
[java] Creating PATH 1248715876078
[java] Creating FILE 1248715876149
[java] 27-jul-2009 19:31:16 com.sfchildren.sbcore.backup.Main main
[java] GRAVE: null
[java] org.apache.hadoop.security.AccessControlException: org.apache.hadoop.security.AccessControlException: Permission denied: user=postgres, access=WRITE, inode="testfile":DrWho:hadoop:rw-r--r--
[java] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[java] at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
[java] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
[java] at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
[java] at org.apache.hadoop.ipc.RemoteException.instantiateException(RemoteException.java:96)
[java] at org.apache.hadoop.ipc.RemoteException.unwrapRemoteException(RemoteException.java:58)
[java] at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.(DFSClient.java:2647)
[java] at org.apache.hadoop.hdfs.DFSClient.create(DFSClient.java:463)
[java] at org.apache.hadoop.hdfs.DistributedFileSystem.create(DistributedFileSystem.java:195)
[java] at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:479)
[java] at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:460)
[java] at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:367)
[java] at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:359)
[java] at com.sfchildren.sbcore.backup.Main.createTmpFile(Main.java:171)
[java] at com.sfchildren.sbcore.backup.Main.main(Main.java:100)
[java] Caused by: org.apache.hadoop.ipc.RemoteException: org.apache.hadoop.security.AccessControlException: Permission denied: user=postgres, access=WRITE, inode="testfile":DrWho:hadoop:rw-r--r--
[java] at org.apache.hadoop.hdfs.server.namenode.PermissionChecker.check(PermissionChecker.java:176)
[java] at org.apache.hadoop.hdfs.server.namenode.PermissionChecker.checkPermission(PermissionChecker.java:111)
[java] at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkPermission(FSNamesystem.java:4486)
[java] at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkPathAccess(FSNamesystem.java:4446)
[java] at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.startFileInternal(FSNamesystem.java:1011)
[java] at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.startFile(FSNamesystem.java:968)
[java] at org.apache.hadoop.hdfs.server.namenode.NameNode.create(NameNode.java:377)
[java] at sun.reflect.GeneratedMethodAccessor7.invoke(Unknown Source)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[java] at java.lang.reflect.Method.invoke(Method.java:597)
[java] at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:508)
[java] at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:959)
[java] at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:955)
[java] at java.security.AccessController.doPrivileged(Native Method)
[java] at javax.security.auth.Subject.doAs(Subject.java:396)
[java] at org.apache.hadoop.ipc.Server$Handler.run(Server.java:953)
[java]
[java] at org.apache.hadoop.ipc.Client.call(Client.java:739)
[java] at org.apache.hadoop.ipc.RPC$Invoker.invoke(RPC.java:220)
[java] at $Proxy0.create(Unknown Source)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[java] at java.lang.reflect.Method.invoke(Method.java:597)
[java] at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:82)
[java] at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:59)
[java] at $Proxy0.create(Unknown Source)
[java] at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.(DFSClient.java:2644)
[java] ... 8 more
Voy a abrir un bug en Hadoop para informar de los problemas que tiene el usar "whoami" en Solaris, para que cuando la propiedad os.name de Java sea SunOS entonces que llame a /usr/xpg4/id -un en vez de whoami
if ( System.getProperty("os.name").equals("SunOS") )Todavía tengo que ver todos los casos en los que se produce y crear un report para crear el bug en Hadoop, de todas formas, espero haber ayudado con el misterio de DrWho.
shellCommand = "/usr/xpg4/id -un";
else
shellCommand = "/usr/bin/id -un";
No hay comentarios:
Publicar un comentario