diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.c b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.c index f393c97..15b53ae 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.c +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/configuration.c @@ -103,7 +103,12 @@ char *resolve_config_path(const char* file_name, const char *root) { real_fname = buffer; } - return (real_fname == NULL) ? NULL : realpath(real_fname, NULL); + char * ret = (real_fname == NULL) ? NULL : realpath(real_fname, NULL); +#ifdef DEBUG + fprintf(stderr, "resolve_config_path(file_name=%s,root=%s)=%s\n", + file_name, root ? root : "null", ret ? ret : "null"); +#endif + return ret; } /** diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c index 9387ba4..cdc6ab8 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c @@ -366,39 +366,59 @@ char *get_tmp_directory(const char *work_dir) { * with the desired permissions. */ int mkdirs(const char* path, mode_t perm) { - char *buffer = strdup(path); - char *token; - int cwd = open("/", O_RDONLY); - if (cwd == -1) { - fprintf(LOGFILE, "Can't open / in %s - %s\n", path, strerror(errno)); - free(buffer); + struct stat sb; + char * npath; + char * p; + if (stat(path, &sb) == 0) { + if (S_ISDIR (sb.st_mode)) { + return 0; + } else { + fprintf(LOGFILE, "Path %s is file not dir\n", path); + return -1; + } + } + npath = strdup(path); + if (npath == NULL) { + fprintf(LOGFILE, "Not enough memory to copy path string"); return -1; } - for(token = strtok(buffer, "/"); token != NULL; token = strtok(NULL, "/")) { - if (mkdirat(cwd, token, perm) != 0) { - if (errno != EEXIST) { - fprintf(LOGFILE, "Can't create directory %s in %s - %s\n", - token, path, strerror(errno)); - close(cwd); - free(buffer); + /* Skip leading slashes. */ + p = npath; + while (*p == '/') { + p++; + } + + while (NULL != (p = strchr(p, '/'))) { + *p = '\0'; + if (stat(npath, &sb) != 0) { + if (mkdir(npath, perm) != 0) { + fprintf(LOGFILE, "Can't create directory %s in %s - %s\n", npath, + path, strerror(errno)); + free(npath); return -1; } - } - int new_dir = openat(cwd, token, O_RDONLY); - close(cwd); - cwd = new_dir; - if (cwd == -1) { - fprintf(LOGFILE, "Can't open %s in %s - %s\n", token, path, - strerror(errno)); - free(buffer); + } else if (!S_ISDIR (sb.st_mode)) { + fprintf(LOGFILE, "Path %s is file not dir\n", npath); + free(npath); return -1; } + *p++ = '/'; /* restore slash */ + while (*p == '/') + p++; + } + + /* Create the final directory component. */ + if (mkdir(npath, perm) != 0) { + fprintf(LOGFILE, "Can't create directory %s - %s\n", npath, + strerror(errno)); + free(npath); + return -1; } - free(buffer); - close(cwd); + free(npath); return 0; } + /** * Function to prepare the container directories. * It creates the container work and log directories. @@ -498,7 +518,7 @@ int is_whitelisted(const char *user) { char **users = whitelist; if (whitelist != NULL) { for(; *users; ++users) { - if (strncmp(*users, user, LOGIN_NAME_MAX) == 0) { + if (strncmp(*users, user, sysconf(_SC_LOGIN_NAME_MAX)) == 0) { free_values(whitelist); return 1; } @@ -970,7 +990,16 @@ int launch_container_as_user(const char *user, const char *app_id, goto cleanup; } +#if defined(__MACH__) + // only those fds are opened assuming no bug + fclose(LOGFILE); + fclose(ERRORFILE); + fclose(stdin); + fclose(stdout); + fclose(stderr); +#else fcloseall(); +#endif umask(0027); if (chdir(work_dir) != 0) { fprintf(LOGFILE, "Can't change directory to %s -%s\n", work_dir, @@ -1252,6 +1281,10 @@ void chown_dir_contents(const char *dir_path, uid_t uid, gid_t gid) { * hierarchy: the top directory of the hierarchy for the NM */ int mount_cgroup(const char *pair, const char *hierarchy) { +#if defined(__FreeBSD__) || defined(__MACH__) + fprintf(LOGFILE, "Failed to mount cgroup controller, not supported\n"); + return -1; +#else char *controller = malloc(strlen(pair)); char *mount_path = malloc(strlen(pair)); char hier_path[PATH_MAX]; @@ -1288,5 +1321,6 @@ int mount_cgroup(const char *pair, const char *hierarchy) { free(mount_path); return result; +#endif } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c index e9a47b1..81c4683 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/test/test-container-executor.c @@ -222,20 +222,22 @@ void test_check_user() { printf("FAIL: failed check for system user root\n"); exit(1); } +#if !defined(__MACH__) // macosx do not have user bin if (check_user("bin") == NULL) { printf("FAIL: failed check for whitelisted system user bin\n"); exit(1); } +#endif } void test_resolve_config_path() { printf("\nTesting resolve_config_path\n"); - if (strcmp(resolve_config_path("/etc/passwd", NULL), "/etc/passwd") != 0) { - printf("FAIL: failed to resolve config_name on an absolute path name: /etc/passwd\n"); + if (strcmp(resolve_config_path("/bin/ls", NULL), "/bin/ls") != 0) { + printf("FAIL: failed to resolve config_name on an absolute path name: /bin/ls\n"); exit(1); } - if (strcmp(resolve_config_path("../etc/passwd", "/etc/passwd"), "/etc/passwd") != 0) { - printf("FAIL: failed to resolve config_name on a relative path name: ../etc/passwd (relative to /etc/passwd)"); + if (strcmp(resolve_config_path("../bin/ls", "/bin/ls"), "/bin/ls") != 0) { + printf("FAIL: failed to resolve config_name on a relative path name: ../bin/ls (relative to /bin/ls)"); exit(1); } }