即check_configuration_permissions会调用is_only_root_writable方法对二进制文件所在目录向上递归做父目录属主的检查,如果有一个目录属主不为root,就会出错。这就要求整个chain上的目录属主都需要是root.
这其实是出于taskcontroller的安全考虑,在代码中定义了不少关于这个可执行文件的权限的验证,只要有一个地方设置不正确,tasktracker都不会正常运行。
cloudra官方文档对这个文件的权限描述如下:
The Task-controller program is used to allow the TaskTracker to run tasks under the Unix account of the user who submitted the job in the first place.
It is a setuid binary that must have a very specific set of permissions and ownership in order to function correctly. In particular, it must:
1)Be owned by root
2)Be owned by a group that contains only the user running the MapReduce daemons
3)Be setuid
4)Be group readable and executable
问题还没有结束,taskcontroller有一个配置文件为taskcontroller.cfg.关于这个配置文件位置的获取比较让人纠结。
搜到有些文档说是通过设置HADOOP_SECURITY_CONF_DIR即可,但是在cdh4.2.0中,这个环境变量并不会生效,可以通过打patch来解决:
https://issues.apache.org/jira/browse/MAPREDUCE-4397
默认情况下,目录取值的方法如下:
#ifndef HADOOP_CONF_DIR //如果编译时不指定HADOOP_CONF_DIR的值,没调用infer_conf_dir方法。
conf_dir = infer_conf_dir(argv[0]);
if (conf_dir == NULL) {
fprintf(LOGFILE, "Couldn't infer HADOOP_CONF_DIR. Please set in environment\n");
return INVALID_CONFIG_FILE;
}
#else
conf_dir = strdup(STRINGIFY(HADOOP_CONF_DIR));
#endif
其中infer_conf_dir方法如下,即通过获取二进制文件的相对路径来得到配置文件的存放目录,比如我们线上执行文件的位置为/home/test/platform/hadoop-2.0.0-mr1-cdh4.2.0/bin/../sbin/Linux-amd64-64/task-controller,配置文件的位置为
/home/test/platform/hadoop-2.0.0-mr1-cdh4.2.0/conf/taskcontroller.cfg:
char *infer_conf_dir(char *executable_file) {
char *result;
char *exec_dup = strdup(executable_file);
char *dir = dirname(exec_dup);
int relative_len = strlen(dir) + 1 + strlen(CONF_DIR_RELATIVE_TO_EXEC) + 1;
char *relative_unresolved = malloc(relative_len);
snprintf(relative_unresolved, relative_len, "%s/%s",
dir, CONF_DIR_RELATIVE_TO_EXEC);
result = realpath(relative_unresolved, NULL);
// realpath will return NULL if the directory doesn't exist