使用fuse-dfs挂载HDFS时,使用命令
./fuse_dfs_wrapper.sh dfs://10.10.102.41:9000 /tmp/hdfs
想要把HDFS mount到/tmp/hdfs下面,总是遇到 port=9000,server=10.10.102.41 fuse-dfs didn't recognize /tmp/hdfs,-2 的错误,core-xml的dfs.default.name是用ip配置的,端口也是9000,但是就是挂载不了,该怎么解决这个错误,Scientific 6.1+hadoop-0.21.0+fuse-2.7.4.
依据上面的环境(Scientific 6.1+hadoop-0.21.0+fuse-2.7.4),查看/var/log/message 里的错误,每次使用命令
./fuse_dfs_wrapper.sh dfs://10.10.102.41:9000 /tmp/hdfs
都能出现上面的 fuse-dfs didn't recognize /tmp/hdfs,-2 的错误,而在/var/log/message 日志文件里显示的是:
ERROR: could not connect to 10.10.102.41:9000 fuse_impls_getattr.c:37
根据上面的错误找到源码,错误出现在hadoop-0.21.0\hadoop-0.21.0\hdfs\src\contrib\fuse-dfs\src下面的fuse_impls_getattr.c源码中,如下面的显示的其中一段:
int dfs_getattr(const char *path, struct stat *st) { TRACE1("getattr", path) // retrieve dfs specific data 28. dfs_context *dfs = (dfs_context*)fuse_get_context()->private_data; // check params and the context var assert(dfs); assert(path); assert(st); // if not connected, try to connect and fail out if we can't. 36. if (NULL == dfs->fs && NULL == (dfs->fs = hdfsConnect(dfs->nn_hostname,dfs->nn_port))) { 37. syslog(LOG_ERR, "ERROR: could not connect to %s:%d %s:%d\n", dfs->nn_hostname, dfs->nn_port,__FILE__, __LINE__); return -EIO; }
/var/log/message出现的错误在第37行,而在28行dfs_context *dfs = (dfs_context*)fuse_get_context()->private_data 那里我调试了程序,打印出了dfs->dfs->nn_hostname和dfs->nn_port的值都是匹配的,但是dfs->fs却是NULL。而在36行那里我修改为if(NULL == (dfs->fs = hdfsConnect(dfs->nn_hostname,dfs->nn_port)))进行了调试,获取得到的dfs->fs仍然还是为空,这也是一直出现 fuse-dfs didn't recognize /tmp/hdfs,-2 错误的原因,因为dfs->fs一直未能获得HDFS的文件handle句柄。
我的疑问一:
hdfsConnect(dfs->nn_hostname,dfs->nn_port)这个函数是否未得到执行,这个函数是在hdfs.h里面声明的,在hdfs.c里面实现。
起初,以为是fuse-dfs源码问题,于是通过SVN更新了hadoop-0.21.0\hadoop-0.21.0\hdfs\src\contrib\fuse-dfs 进行重新的编译,编译成功后,进行
./fuse_dfs_wrapper.sh dfs://10.10.102.41:9000 /tmp/hdfs挂载,虽然不再出现 fuse-dfs didn't recognize /tmp/hdfs,-2 的错误,依旧挂载不成功,再次查看了/var/log/message日志文件,找到更新后的hadoop-0.21.0\hadoop-0.21.0\hdfs\src\contrib\fuse-dfs\src的错误源: 错误来自于下面的子函数中的98行:ERROR:Unable to create fs for user root (我用的是root挂载,用其他用户也是如此)
hdfsFS doConnectAsUser(const char *hostname, int port) { uid_t uid = fuse_get_context()->uid; char *user = getUsername(uid); int ret; hdfsFS fs = NULL; if (NULL == user) { goto done; } ret = pthread_mutex_lock(&tableMutex); assert(0 == ret); fs = findFs(user); if (NULL == fs) { 96. fs = hdfsConnectAsUserNewInstance(hostname, port, user); 97. if (NULL == fs) { 98. ERROR("Unable to create fs for user %s", user); goto done; if (-1 == insertFs(user, fs)) { ERROR("Unable to cache fs for user %s", user); } }
我的疑问二:
上面的错误都出现在hdfs.c中的函数里,而出错的原因都是无法获取fs的句柄,而防火墙确实是已经关了,但是fs依然是NULL,猜想应该出错在hdfs.c这部分,因为不了解hdfs.h,hdfs.c,libhdfs.so 这几个文件的原因不知道如何去解决这个问题。
找到原因,主要是jar包问题,源码没有问题,CLASSPATH必须完整的设置出hadoop的各个jar包,网上google下发现hadoop有个ClASSPATH的bug,大概是发现不了jar导致的fuse-dfs didn't recognize /tmp/hdfs,-2,虽然会出现这个提示,但是查看的/var/log/message是可以成功挂载上去的。