|
@@ -67,6 +67,8 @@ static const int DEFAULT_MIN_USERID = 1000;
|
|
|
|
|
|
static const char* DEFAULT_BANNED_USERS[] = {"mapred", "hdfs", "bin", 0};
|
|
static const char* DEFAULT_BANNED_USERS[] = {"mapred", "hdfs", "bin", 0};
|
|
|
|
|
|
|
|
+static const int DEFAULT_MOUNT_CGROUP_SUPPORT_ENABLED = 0;
|
|
|
|
+
|
|
//location of traffic control binary
|
|
//location of traffic control binary
|
|
static const char* TC_BIN = "/sbin/tc";
|
|
static const char* TC_BIN = "/sbin/tc";
|
|
static const char* TC_MODIFY_STATE_OPTS [] = { "-b" , NULL};
|
|
static const char* TC_MODIFY_STATE_OPTS [] = { "-b" , NULL};
|
|
@@ -1065,6 +1067,12 @@ int is_tc_support_enabled() {
|
|
return is_feature_enabled(TC_SUPPORT_ENABLED_KEY,
|
|
return is_feature_enabled(TC_SUPPORT_ENABLED_KEY,
|
|
DEFAULT_TC_SUPPORT_ENABLED);
|
|
DEFAULT_TC_SUPPORT_ENABLED);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+int is_mount_cgroups_support_enabled() {
|
|
|
|
+ return is_feature_enabled(MOUNT_CGROUP_SUPPORT_ENABLED_KEY,
|
|
|
|
+ DEFAULT_MOUNT_CGROUP_SUPPORT_ENABLED);
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Function to prepare the application directories for the container.
|
|
* Function to prepare the application directories for the container.
|
|
*/
|
|
*/
|
|
@@ -2187,20 +2195,25 @@ void chown_dir_contents(const char *dir_path, uid_t uid, gid_t gid) {
|
|
DIR *dp;
|
|
DIR *dp;
|
|
struct dirent *ep;
|
|
struct dirent *ep;
|
|
|
|
|
|
- char *path_tmp = malloc(strlen(dir_path) + NAME_MAX + 2);
|
|
|
|
|
|
+ size_t len = strlen(dir_path) + NAME_MAX + 2;
|
|
|
|
+ char *path_tmp = malloc(len);
|
|
if (path_tmp == NULL) {
|
|
if (path_tmp == NULL) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- char *buf = stpncpy(path_tmp, dir_path, strlen(dir_path));
|
|
|
|
- *buf++ = '/';
|
|
|
|
-
|
|
|
|
dp = opendir(dir_path);
|
|
dp = opendir(dir_path);
|
|
if (dp != NULL) {
|
|
if (dp != NULL) {
|
|
while ((ep = readdir(dp)) != NULL) {
|
|
while ((ep = readdir(dp)) != NULL) {
|
|
- stpncpy(buf, ep->d_name, strlen(ep->d_name));
|
|
|
|
- buf[strlen(ep->d_name)] = '\0';
|
|
|
|
- change_owner(path_tmp, uid, gid);
|
|
|
|
|
|
+ if (strcmp(ep->d_name, ".") != 0 &&
|
|
|
|
+ strcmp(ep->d_name, "..") != 0 &&
|
|
|
|
+ strstr(ep->d_name, "..") == NULL) {
|
|
|
|
+ int result = snprintf(path_tmp, len, "%s/%s", dir_path, ep->d_name);
|
|
|
|
+ if (result > 0 && result < len) {
|
|
|
|
+ change_owner(path_tmp, uid, gid);
|
|
|
|
+ } else {
|
|
|
|
+ fprintf(LOGFILE, "Ignored %s/%s due to length", dir_path, ep->d_name);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
closedir(dp);
|
|
closedir(dp);
|
|
}
|
|
}
|
|
@@ -2223,13 +2236,29 @@ int mount_cgroup(const char *pair, const char *hierarchy) {
|
|
char *mount_path = malloc(strlen(pair));
|
|
char *mount_path = malloc(strlen(pair));
|
|
char hier_path[EXECUTOR_PATH_MAX];
|
|
char hier_path[EXECUTOR_PATH_MAX];
|
|
int result = 0;
|
|
int result = 0;
|
|
|
|
+ size_t len = strlen(pair);
|
|
|
|
|
|
- if (get_kv_key(pair, controller, strlen(pair)) < 0 ||
|
|
|
|
- get_kv_value(pair, mount_path, strlen(pair)) < 0) {
|
|
|
|
|
|
+ if (controller == NULL || mount_path == NULL) {
|
|
|
|
+ fprintf(LOGFILE, "Failed to mount cgroup controller; not enough memory\n");
|
|
|
|
+ result = OUT_OF_MEMORY;
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+ if (hierarchy == NULL || strstr(hierarchy, "..") != NULL) {
|
|
|
|
+ fprintf(LOGFILE, "Unsupported cgroup hierarhy path detected.\n");
|
|
|
|
+ result = INVALID_COMMAND_PROVIDED;
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+ if (get_kv_key(pair, controller, len) < 0 ||
|
|
|
|
+ get_kv_value(pair, mount_path, len) < 0) {
|
|
fprintf(LOGFILE, "Failed to mount cgroup controller; invalid option: %s\n",
|
|
fprintf(LOGFILE, "Failed to mount cgroup controller; invalid option: %s\n",
|
|
pair);
|
|
pair);
|
|
result = -1;
|
|
result = -1;
|
|
} else {
|
|
} else {
|
|
|
|
+ if (strstr(mount_path, "..") != NULL) {
|
|
|
|
+ fprintf(LOGFILE, "Unsupported cgroup mount path detected.\n");
|
|
|
|
+ result = INVALID_COMMAND_PROVIDED;
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
if (mount("none", mount_path, "cgroup", 0, controller) == 0) {
|
|
if (mount("none", mount_path, "cgroup", 0, controller) == 0) {
|
|
char *buf = stpncpy(hier_path, mount_path, strlen(mount_path));
|
|
char *buf = stpncpy(hier_path, mount_path, strlen(mount_path));
|
|
*buf++ = '/';
|
|
*buf++ = '/';
|
|
@@ -2237,13 +2266,20 @@ int mount_cgroup(const char *pair, const char *hierarchy) {
|
|
|
|
|
|
// create hierarchy as 0750 and chown to Hadoop NM user
|
|
// create hierarchy as 0750 and chown to Hadoop NM user
|
|
const mode_t perms = S_IRWXU | S_IRGRP | S_IXGRP;
|
|
const mode_t perms = S_IRWXU | S_IRGRP | S_IXGRP;
|
|
|
|
+ struct stat sb;
|
|
|
|
+ if (stat(hier_path, &sb) == 0 &&
|
|
|
|
+ (sb.st_uid != nm_uid || sb.st_gid != nm_gid)) {
|
|
|
|
+ fprintf(LOGFILE, "cgroup hierarchy %s already owned by another user %d\n", hier_path, sb.st_uid);
|
|
|
|
+ result = INVALID_COMMAND_PROVIDED;
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
if (mkdirs(hier_path, perms) == 0) {
|
|
if (mkdirs(hier_path, perms) == 0) {
|
|
change_owner(hier_path, nm_uid, nm_gid);
|
|
change_owner(hier_path, nm_uid, nm_gid);
|
|
chown_dir_contents(hier_path, nm_uid, nm_gid);
|
|
chown_dir_contents(hier_path, nm_uid, nm_gid);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
fprintf(LOGFILE, "Failed to mount cgroup controller %s at %s - %s\n",
|
|
fprintf(LOGFILE, "Failed to mount cgroup controller %s at %s - %s\n",
|
|
- controller, mount_path, strerror(errno));
|
|
|
|
|
|
+ controller, mount_path, strerror(errno));
|
|
// if controller is already mounted, don't stop trying to mount others
|
|
// if controller is already mounted, don't stop trying to mount others
|
|
if (errno != EBUSY) {
|
|
if (errno != EBUSY) {
|
|
result = -1;
|
|
result = -1;
|
|
@@ -2251,6 +2287,7 @@ int mount_cgroup(const char *pair, const char *hierarchy) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+cleanup:
|
|
free(controller);
|
|
free(controller);
|
|
free(mount_path);
|
|
free(mount_path);
|
|
|
|
|