您的位置:首页 > 运维架构

hadoop fuse挂载问题 (fuse-dfs didn't recognize /tmp/hdfs, -2)

2014-05-15 17:05 573 查看
使用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);
}
}


出错的原因在执行96: fs = hdfsConnectAsUserNewInstance(hostname, port, user); 后得到的fs仍然我NULL,而hdfsConnectAsUserNewInstance也是声明在hdfs.h,实现在hdfs.c函数当中,但是当执行了上面的 fs = hdfsConnectAsUserNewInstance(hostname, port, user),参数hostname,port,user我调试了都是对应正确的,但是fs得到的值仍然是NULL,出错的本质跟上面未改变源码时的情况一样,依旧是无法获取到FS的句柄,我也看了hdfs.c和hdfs.h这两个文件,hdfs.h负责声明,hdfs.c负责实现,而在hadoop0.21.0中在未编译之前还有这个文件libhdfs.so的库文件,是否在执行过程中调用的是这个库文件去执行,而在我成功编译后在对应的编译目录也出现了libhdfs.so,libhdfs.so.0
libhdfs.so.0.0.0对应的库文件。

我的疑问二:

上面的错误都出现在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是可以成功挂载上去的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: