Disable mounting cgroups by default (miklos.szeg...@cloudera.com via rkanter)

(cherry picked from commit 351cf87c92872d90f62c476f85ae4d02e485769c)
(cherry picked from commit d61d84279f7f22867c23dd95e8bfeb70ea7e0690)
(cherry picked from commit f5fd5aa025c904e9a2ff8c5fd932aaed2363a6a0)
(cherry picked from commit e20a840174bc2b27fcc0935e0086977bd6fbfcb3)


Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/1569cc62
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/1569cc62
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/1569cc62

Branch: refs/heads/branch-2.7
Commit: 1569cc62cda563fed1db26c3e47d884abe1c5a45
Parents: af3b37d
Author: Andrew Purtell <apurt...@salesforce.com>
Authored: Mon Nov 12 12:40:47 2018 -0800
Committer: Konstantin V Shvachko <s...@apache.org>
Committed: Wed Nov 28 16:49:40 2018 -0800

----------------------------------------------------------------------
 .../impl/container-executor.c                   | 83 +++++++++++++++++---
 .../impl/container-executor.h                   |  7 +-
 .../main/native/container-executor/impl/main.c  | 23 ++++--
 .../src/site/markdown/NodeManagerCgroups.md     | 10 +++
 4 files changed, 103 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/1569cc62/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c
----------------------------------------------------------------------
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 9601264..b262ef3 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
@@ -62,6 +62,8 @@ static const int DEFAULT_MIN_USERID = 1000;
 
 static const char* DEFAULT_BANNED_USERS[] = {"mapred", "hdfs", "bin", 0};
 
+static const int DEFAULT_MOUNT_CGROUP_SUPPORT_ENABLED = 0;
+
 //struct to store the user details
 struct passwd *user_detail = NULL;
 
@@ -984,6 +986,36 @@ int create_log_dirs(const char *app_id, char * const * 
log_dirs) {
 }
 
 
+static int is_feature_enabled(const char* feature_key, int default_value) {
+    char *enabled_str = get_value(feature_key, &executor_cfg);
+    int enabled = default_value;
+
+    if (enabled_str != NULL) {
+        char *end_ptr = NULL;
+        enabled = strtol(enabled_str, &end_ptr, 10);
+
+        if ((enabled_str == end_ptr || *end_ptr != '\0') ||
+            (enabled < 0 || enabled > 1)) {
+              fprintf(LOGFILE, "Illegal value '%s' for '%s' in configuration. "
+              "Using default value: %d.\n", enabled_str, feature_key,
+              default_value);
+              fflush(LOGFILE);
+              free(enabled_str);
+              return default_value;
+        }
+
+        free(enabled_str);
+        return enabled;
+    } else {
+        return default_value;
+    }
+}
+
+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.
  */
@@ -1466,20 +1498,25 @@ void chown_dir_contents(const char *dir_path, uid_t 
uid, gid_t gid) {
   DIR *dp;
   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) {
     return;
   }
 
-  char *buf = stpncpy(path_tmp, dir_path, strlen(dir_path));
-  *buf++ = '/';
-
   dp = opendir(dir_path);
   if (dp != NULL) {
-    while (ep = readdir(dp)) {
-      stpncpy(buf, ep->d_name, strlen(ep->d_name));
-      buf[strlen(ep->d_name)] = '\0';
-      change_owner(path_tmp, uid, gid);
+    while ((ep = readdir(dp)) != NULL) {
+      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);
   }
@@ -1502,13 +1539,29 @@ int mount_cgroup(const char *pair, const char 
*hierarchy) {
   char *mount_path = malloc(strlen(pair));
   char hier_path[EXECUTOR_PATH_MAX];
   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",
               pair);
     result = -1;
   } 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) {
       char *buf = stpncpy(hier_path, mount_path, strlen(mount_path));
       *buf++ = '/';
@@ -1516,13 +1569,20 @@ int mount_cgroup(const char *pair, const char 
*hierarchy) {
 
       // create hierarchy as 0750 and chown to Hadoop NM user
       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) {
         change_owner(hier_path, nm_uid, nm_gid);
         chown_dir_contents(hier_path, nm_uid, nm_gid);
       }
     } else {
       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 (errno != EBUSY) {
         result = -1;
@@ -1530,6 +1590,7 @@ int mount_cgroup(const char *pair, const char *hierarchy) 
{
     }
   }
 
+cleanup:
   free(controller);
   free(mount_path);
 

http://git-wip-us.apache.org/repos/asf/hadoop/blob/1569cc62/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
index d80679e..644233f 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h
@@ -54,7 +54,8 @@ enum errorcodes {
   INVALID_CONFIG_FILE =  24,
   SETSID_OPER_FAILED = 25,
   WRITE_PIDFILE_FAILED = 26,
-  WRITE_CGROUP_FAILED = 27
+  WRITE_CGROUP_FAILED = 27,
+  FEATURE_DISABLED = 32
 };
 
 #define NM_GROUP_KEY "yarn.nodemanager.linux-container-executor.group"
@@ -66,6 +67,7 @@ enum errorcodes {
 #define MIN_USERID_KEY "min.user.id"
 #define BANNED_USERS_KEY "banned.users"
 #define ALLOWED_SYSTEM_USERS_KEY "allowed.system.users"
+#define MOUNT_CGROUP_SUPPORT_ENABLED_KEY "feature.mount-cgroup.enabled"
 #define TMP_DIR "tmp"
 
 extern struct passwd *user_detail;
@@ -225,3 +227,6 @@ int check_dir(char* npath, mode_t st_mode, mode_t desired,
 
 int create_validate_dir(char* npath, mode_t perm, char* path,
    int finalComponent);
+
+/** Check if cgroup mount support is enabled in configuration. */
+int is_mount_cgroups_support_enabled();

http://git-wip-us.apache.org/repos/asf/hadoop/blob/1569cc62/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
index bfcd851..17852cd 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c
@@ -76,6 +76,10 @@ static void flush_and_close_log_files() {
   }
 }
 
+static void display_feature_disabled_message(const char* name) {
+  fprintf(ERRORFILE, "Feature disabled: %s\n", name);
+}
+
 int main(int argc, char **argv) {
   int invalid_args = 0; 
   int do_check_setup = 0;
@@ -195,15 +199,18 @@ int main(int argc, char **argv) {
   }
 
   if (do_mount_cgroups) {
-    optind++;
-    char *hierarchy = argv[optind++];
-    int result = 0;
-
-    while (optind < argc && result == 0) {
-      result = mount_cgroup(argv[optind++], hierarchy);
+    if (is_mount_cgroups_support_enabled()) {
+      optind++;
+      char *hierarchy = argv[optind++];
+      int result = 0;
+      while (optind < argc && result == 0) {
+        result = mount_cgroup(argv[optind++], hierarchy);
+      }
+      return result;
+    } else {
+      display_feature_disabled_message("mount cgroup");
+      return FEATURE_DISABLED;
     }
-
-    return result;
   }
 
   //checks done for user name

http://git-wip-us.apache.org/repos/asf/hadoop/blob/1569cc62/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/NodeManagerCgroups.md
----------------------------------------------------------------------
diff --git 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/NodeManagerCgroups.md
 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/NodeManagerCgroups.md
index 79a428d..5014a95 100644
--- 
a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/NodeManagerCgroups.md
+++ 
b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/NodeManagerCgroups.md
@@ -43,6 +43,16 @@ The following settings are related to limiting resource 
usage of YARN containers
 | `yarn.nodemanager.resource.percentage-physical-cpu-limit` | This setting 
lets you limit the cpu usage of all YARN containers. It sets a hard upper limit 
on the cumulative CPU usage of the containers. For example, if set to 60, the 
combined CPU usage of all YARN containers will not exceed 60%. |
 | `yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage` | 
CGroups allows cpu usage limits to be hard or soft. When this setting is true, 
containers cannot use more CPU usage than allocated even if spare CPU is 
available. This ensures that containers can only use CPU that they were 
allocated. When set to false, containers can use spare CPU if available. It 
should be noted that irrespective of whether set to true or false, at no time 
can the combined CPU usage of all containers exceed the value specified in 
"yarn.nodemanager.resource.percentage-physical-cpu-limit". |
 
+CGroups mount options
+---------------------
+
+YARN uses CGroups through a directory structure mounted into the file system 
by the kernel. There are three options to attach to CGroups.
+
+| Option | Description |
+|:---- |:---- |
+| Discover CGroups mounted already | This should be used on newer systems like 
RHEL7 or Ubuntu16 or if the administrator mounts CGroups before YARN starts. 
Set `yarn.nodemanager.linux-container-executor.cgroups.mount` to false and 
leave other settings set to their defaults. YARN will locate the mount points 
in `/proc/mounts`. Common locations include `/sys/fs/cgroup` and `/cgroup`. The 
default location can vary depending on the Linux distribution in use.|
+| CGroups mounted by YARN | IMPORTANT: This option is deprecated due to 
security reasons with the `container-executor.cfg` option 
`feature.mount-cgroup.enabled=0` by default. Please mount cgroups before 
launching YARN.|
+
 CGroups and security
 --------------------
 


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org
For additional commands, e-mail: common-commits-h...@hadoop.apache.org

Reply via email to