/*
 * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include <string.h>
#include <math.h>
#include <errno.h>
#include <sys/vfs.h>
#include "cgroupSubsystem_linux.hpp"
#include "cgroupV1Subsystem_linux.hpp"
#include "cgroupV2Subsystem_linux.hpp"
#include "cgroupUtil_linux.hpp"
#include "logging/log.hpp"
#include "memory/allocation.hpp"
#include "os_linux.hpp"
#include "runtime/globals.hpp"
#include "runtime/os.hpp"
#include "utilities/globalDefinitions.hpp"

// Inlined from <linux/magic.h> for portability.
#ifndef CGROUP2_SUPER_MAGIC
#  define CGROUP2_SUPER_MAGIC 0x63677270
#endif

// controller names have to match the *_IDX indices
static const char* cg_controller_name[] = { "cpuset", "cpu", "cpuacct", "memory", "pids" };
static inline int cg_v2_controller_index(const char* name) {
  if (strcmp(name, "cpuset") == 0) {
    return CPUSET_IDX;
  } else if (strcmp(name, "cpu") == 0) {
    return CPU_IDX;
  } else if (strcmp(name, "memory") == 0) {
    return MEMORY_IDX;
  } else if (strcmp(name, "pids") == 0) {
    return PIDS_IDX;
  } else {
    return -1;
  }
}

CgroupSubsystem* CgroupSubsystemFactory::create() {
  CgroupV1MemoryController* memory = nullptr;
  CgroupV1Controller* cpuset = nullptr;
  CgroupV1CpuController* cpu = nullptr;
  CgroupV1Controller* cpuacct = nullptr;
  CgroupV1Controller* pids = nullptr;
  CgroupInfo cg_infos[CG_INFO_LENGTH];
  u1 cg_type_flags = INVALID_CGROUPS_GENERIC;
  const char* proc_cgroups = "/proc/cgroups";
  const char* sys_fs_cgroup_cgroup_controllers = "/sys/fs/cgroup/cgroup.controllers";
  const char* controllers_file = proc_cgroups;
  const char* proc_self_cgroup = "/proc/self/cgroup";
  const char* proc_self_mountinfo = "/proc/self/mountinfo";
  const char* sys_fs_cgroup = "/sys/fs/cgroup";
  struct statfs fsstat = {};
  bool cgroups_v2_enabled = false;

  // Assume cgroups v2 is usable by the JDK iff /sys/fs/cgroup has the cgroup v2
  // file system magic.  If it does not then heuristics are required to determine
  // if cgroups v1 is usable or not.
  if (statfs(sys_fs_cgroup, &fsstat) != -1) {
    cgroups_v2_enabled = (fsstat.f_type == CGROUP2_SUPER_MAGIC);
    if (cgroups_v2_enabled) {
      controllers_file = sys_fs_cgroup_cgroup_controllers;
    }
  }

  bool valid_cgroup = determine_type(cg_infos, cgroups_v2_enabled, controllers_file, proc_self_cgroup, proc_self_mountinfo, &cg_type_flags);

  if (!valid_cgroup) {
    // Could not detect cgroup type
    return nullptr;
  }
  assert(is_valid_cgroup(&cg_type_flags), "Expected valid cgroup type");

  if (is_cgroup_v2(&cg_type_flags)) {
    // Cgroups v2 case, we have all the info we need.
    // Construct the subsystem, free resources and return
    // Note: We use the memory for non-cpu non-memory controller look-ups.
    //       Perhaps we ought to have separate controllers for all.
    CgroupV2Controller mem_other = CgroupV2Controller(cg_infos[MEMORY_IDX]._mount_path,
                                                      cg_infos[MEMORY_IDX]._cgroup_path,
                                                      cg_infos[MEMORY_IDX]._read_only);
    CgroupV2MemoryController* memory = new CgroupV2MemoryController(mem_other);
    CgroupV2CpuController* cpu = new CgroupV2CpuController(CgroupV2Controller(cg_infos[CPU_IDX]._mount_path,
                                                                              cg_infos[CPU_IDX]._cgroup_path,
                                                                              cg_infos[CPU_IDX]._read_only));
    log_debug(os, container)("Detected cgroups v2 unified hierarchy");
    cleanup(cg_infos);
    return new CgroupV2Subsystem(memory, cpu, mem_other);
  }

  /*
   * Cgroup v1 case:
   *
   * Use info gathered previously from /proc/self/cgroup
   * and map host mount point to
   * local one via /proc/self/mountinfo content above
   *
   * Docker example:
   * 5:memory:/docker/6558aed8fc662b194323ceab5b964f69cf36b3e8af877a14b80256e93aecb044
   *
   * Host example:
   * 5:memory:/user.slice
   *
   * Construct a path to the process specific memory and cpuset
   * cgroup directory.
   *
   * For a container running under Docker from memory example above
   * the paths would be:
   *
   * /sys/fs/cgroup/memory
   *
   * For a Host from memory example above the path would be:
   *
   * /sys/fs/cgroup/memory/user.slice
   *
   */
  assert(is_cgroup_v1(&cg_type_flags), "Cgroup v1 expected");
  for (int i = 0; i < CG_INFO_LENGTH; i++) {
    CgroupInfo info = cg_infos[i];
    if (info._data_complete) { // pids controller might have incomplete data
      if (strcmp(info._name, "memory") == 0) {
        memory = new CgroupV1MemoryController(CgroupV1Controller(info._root_mount_path, info._mount_path, info._read_only));
        memory->set_subsystem_path(info._cgroup_path);
      } else if (strcmp(info._name, "cpuset") == 0) {
        cpuset = new CgroupV1Controller(info._root_mount_path, info._mount_path, info._read_only);
        cpuset->set_subsystem_path(info._cgroup_path);
      } else if (strcmp(info._name, "cpu") == 0) {
        cpu = new CgroupV1CpuController(CgroupV1Controller(info._root_mount_path, info._mount_path, info._read_only));
        cpu->set_subsystem_path(info._cgroup_path);
      } else if (strcmp(info._name, "cpuacct") == 0) {
        cpuacct = new CgroupV1Controller(info._root_mount_path, info._mount_path, info._read_only);
        cpuacct->set_subsystem_path(info._cgroup_path);
      } else if (strcmp(info._name, "pids") == 0) {
        pids = new CgroupV1Controller(info._root_mount_path, info._mount_path, info._read_only);
        pids->set_subsystem_path(info._cgroup_path);
      }
    } else {
      log_debug(os, container)("CgroupInfo for %s not complete", cg_controller_name[i]);
    }
  }
  cleanup(cg_infos);
  return new CgroupV1Subsystem(cpuset, cpu, cpuacct, pids, memory);
}

void CgroupSubsystemFactory::set_controller_paths(CgroupInfo* cg_infos,
                                                  int controller,
                                                  const char* name,
                                                  char* mount_path,
                                                  char* root_path,
                                                  bool read_only) {
  if (cg_infos[controller]._mount_path != nullptr) {
    // On some systems duplicate controllers get mounted in addition to
    // the main cgroup controllers most likely under /sys/fs/cgroup. In that
    // case pick the one under /sys/fs/cgroup and discard others.
    if (strstr(cg_infos[controller]._mount_path, "/sys/fs/cgroup") != cg_infos[controller]._mount_path) {
      log_debug(os, container)("Duplicate %s controllers detected. Picking %s, skipping %s.",
                               name, mount_path, cg_infos[controller]._mount_path);
      os::free(cg_infos[controller]._mount_path);
      os::free(cg_infos[controller]._root_mount_path);
      cg_infos[controller]._mount_path = os::strdup(mount_path);
      cg_infos[controller]._root_mount_path = os::strdup(root_path);
      cg_infos[controller]._read_only = read_only;
    } else {
      log_debug(os, container)("Duplicate %s controllers detected. Picking %s, skipping %s.",
                               name, cg_infos[controller]._mount_path, mount_path);
    }
  } else {
    cg_infos[controller]._mount_path = os::strdup(mount_path);
    cg_infos[controller]._root_mount_path = os::strdup(root_path);
    cg_infos[controller]._read_only = read_only;
  }
}

/*
 * Determine whether or not the mount options, which are comma separated,
 * contain the 'ro' string.
 */
static bool find_ro_opt(char* mount_opts) {
  char* token;
  char* mo_ptr = mount_opts;
  // mount options are comma-separated (man proc).
  while ((token = strsep(&mo_ptr, ",")) != nullptr) {
    if (strcmp(token, "ro") == 0) {
      return true;
    }
  }
  return false;
}

/*
 * Read values of a /proc/self/mountinfo line into variables. For cgroups v1
 * super options are needed. On cgroups v2 super options are not used.
 *
 * The scanning of a single mountinfo line entry is as follows:
 *
 * 36  35  98:0      /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
 * (1) (2) (3):(4)   (5)   (6)      (7)      (8)   (9) (10)   (11)         (12)
 *
 * The numbers in parentheses are labels for the descriptions below:
 *
 *  (1)   mount ID:        matched with '%*d' and discarded
 *  (2)   parent ID:       matched with '%*d' and discarded
 *  (3)   major:           ---,---> major, minor separated by ':'. matched with '%*d:%*d' and discarded
 *  (4)   minor:           ---'
 *  (5)   root:            matched with '%s' and captured in 'tmproot'. Must be non-empty.
 *  (6)   mount point:     matched with '%s' and captured in 'tmpmount'. Must be non-empty.
 *  (7)   mount options:   matched with '%s' and captured in 'mount_opts'. Must be non-empty.
 *  (8)   optional fields: ---,---> matched with '%*[^-]-'. Anything not a hyphen, followed by a hyphen
 *  (9)   separator:       ---'     and discarded. Note: The discarded match is space characters if there
 *                                  are no optionals. Otherwise it includes the optional fields as well.
 * (10)   filesystem type: matched with '%s' and captured in 'tmp_fs_type'
 * (11)   mount source:    matched with '%*s' and discarded
 * (12)   super options:   matched with '%s' and captured in 'tmpcgroups'
 */
static inline bool match_mount_info_line(char* line,
                                         char* tmproot,
                                         char* tmpmount,
                                         char* mount_opts,
                                         char* tmp_fs_type,
                                         char* tmpcgroups) {
 return sscanf(line,
               "%*d %*d %*d:%*d %s %s %s%*[^-]- %s %*s %s",
               tmproot,
               tmpmount,
               mount_opts,
               tmp_fs_type,
               tmpcgroups) == 5;
}

bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos,
                                            bool cgroups_v2_enabled,
                                            const char* controllers_file,
                                            const char* proc_self_cgroup,
                                            const char* proc_self_mountinfo,
                                            u1* flags) {
  FILE *mntinfo = nullptr;
  FILE* controllers = nullptr;
  FILE *cgroup = nullptr;
  char buf[MAXPATHLEN+1];
  char *p;
  // true iff all required controllers, memory, cpu, cpuacct are enabled
  // at the kernel level.
  // pids might not be enabled on older Linux distros (SLES 12.1, RHEL 7.1)
  // cpuset might not be enabled on newer Linux distros (Fedora 41)
  bool all_required_controllers_enabled = true;

  // If cgroups v2 is enabled, open /sys/fs/cgroup/cgroup.controllers.  If not, open /proc/cgroups.
  controllers = os::fopen(controllers_file, "r");
  if (controllers == nullptr) {
    log_debug(os, container)("Can't open %s, %s", controllers_file, os::strerror(errno));
    *flags = INVALID_CGROUPS_GENERIC;
    return false;
  }

  if (cgroups_v2_enabled) {
    /*
     * cgroups v2 is enabled.  For cgroups v2 (unified hierarchy), the cpu and memory
     * controllers must be enabled.
     */
    if ((p = fgets(buf, MAXPATHLEN, controllers)) != nullptr) {
      char* controller = nullptr;
      #define ISSPACE_CHARS " \n\t\r\f\v"
      while ((controller = strsep(&p, ISSPACE_CHARS)) != nullptr) {
        int i;
        if ((i = cg_v2_controller_index(controller)) != -1) {
          cg_infos[i]._name = os::strdup(controller);
          cg_infos[i]._enabled = true;
          if (i == PIDS_IDX || i == CPUSET_IDX) {
            log_debug(os, container)("Detected optional %s controller entry in %s",
                                     controller, controllers_file);
          }
        }
      }
      #undef ISSPACE_CHARS
    } else {
      log_debug(os, container)("Can't read %s, %s", controllers_file, os::strerror(errno));
      *flags = INVALID_CGROUPS_V2;
      fclose(controllers);
      return false;
    }
    for (int i = 0; i < CG_INFO_LENGTH; i++) {
      // cgroups v2 does not have cpuacct.
      if (i == CPUACCT_IDX) {
        continue;
      }
      // For cgroups v2, cpuacct is rolled into cpu, and the pids and cpuset controllers
      // are optional; the remaining controllers, cpu and memory, are required.
      if (i == CPU_IDX || i == MEMORY_IDX) {
        all_required_controllers_enabled = all_required_controllers_enabled && cg_infos[i]._enabled;
      }
      if (log_is_enabled(Debug, os, container) && !cg_infos[i]._enabled) {
        log_debug(os, container)("controller %s is not enabled", cg_controller_name[i]);
      }
    }
  } else {
    /*
     * The /sys/fs/cgroup filesystem magic hint suggests we have cg v1.  Read /proc/cgroups; for
     * cgroups v1 hierarchy (hybrid or legacy), cpu, cpuacct, cpuset, and memory controllers must
     * have non-zero for the hierarchy ID field and relevant controllers mounted.
     */
    while ((p = fgets(buf, MAXPATHLEN, controllers)) != nullptr) {
      char name[MAXPATHLEN+1];
      int  hierarchy_id;
      int  enabled;

      // Format of /proc/cgroups documented via man 7 cgroups
      if (sscanf(p, "%s %d %*d %d", name, &hierarchy_id, &enabled) != 3) {
        continue;
      }
      if (strcmp(name, "memory") == 0) {
        cg_infos[MEMORY_IDX]._name = os::strdup(name);
        cg_infos[MEMORY_IDX]._hierarchy_id = hierarchy_id;
        cg_infos[MEMORY_IDX]._enabled = (enabled == 1);
      } else if (strcmp(name, "cpuset") == 0) {
        cg_infos[CPUSET_IDX]._name = os::strdup(name);
        cg_infos[CPUSET_IDX]._hierarchy_id = hierarchy_id;
        cg_infos[CPUSET_IDX]._enabled = (enabled == 1);
      } else if (strcmp(name, "cpu") == 0) {
        cg_infos[CPU_IDX]._name = os::strdup(name);
        cg_infos[CPU_IDX]._hierarchy_id = hierarchy_id;
        cg_infos[CPU_IDX]._enabled = (enabled == 1);
      } else if (strcmp(name, "cpuacct") == 0) {
        cg_infos[CPUACCT_IDX]._name = os::strdup(name);
        cg_infos[CPUACCT_IDX]._hierarchy_id = hierarchy_id;
        cg_infos[CPUACCT_IDX]._enabled = (enabled == 1);
      } else if (strcmp(name, "pids") == 0) {
        log_debug(os, container)("Detected optional pids controller entry in %s", controllers_file);
        cg_infos[PIDS_IDX]._name = os::strdup(name);
        cg_infos[PIDS_IDX]._hierarchy_id = hierarchy_id;
        cg_infos[PIDS_IDX]._enabled = (enabled == 1);
      }
    }
    for (int i = 0; i < CG_INFO_LENGTH; i++) {
      // pids controller is optional. All other controllers are required
      if (i != PIDS_IDX) {
        all_required_controllers_enabled = all_required_controllers_enabled && cg_infos[i]._enabled;
      }
      if (log_is_enabled(Debug, os, container) && !cg_infos[i]._enabled) {
        log_debug(os, container)("controller %s is not enabled", cg_controller_name[i]);
      }
    }
  }
  fclose(controllers);

  if (!all_required_controllers_enabled) {
    // one or more required controllers disabled, disable container support
    log_debug(os, container)("One or more required controllers disabled at kernel level.");
    cleanup(cg_infos);
    *flags = INVALID_CGROUPS_GENERIC;
    return false;
  }

  /*
   * Read /proc/self/cgroup and determine:
   *  - the cgroup path for cgroups v2 or
   *  - on a cgroups v1 system, collect info for mapping
   *    the host mount point to the local one via /proc/self/mountinfo below.
   */
  cgroup = os::fopen(proc_self_cgroup, "r");
  if (cgroup == nullptr) {
    log_debug(os, container)("Can't open %s, %s",
                             proc_self_cgroup, os::strerror(errno));
    cleanup(cg_infos);
    *flags = INVALID_CGROUPS_GENERIC;
    return false;
  }

  while ((p = fgets(buf, MAXPATHLEN, cgroup)) != nullptr) {
    char *controllers;
    char *token;
    char *hierarchy_id_str;
    int  hierarchy_id;
    char *cgroup_path;

    hierarchy_id_str = strsep(&p, ":");
    hierarchy_id = atoi(hierarchy_id_str);
    /* Get controllers and base */
    controllers = strsep(&p, ":");
    cgroup_path = strsep(&p, "\n");

    if (controllers == nullptr) {
      continue;
    }

    while (!cgroups_v2_enabled && (token = strsep(&controllers, ",")) != nullptr) {
      if (strcmp(token, "memory") == 0) {
        assert(hierarchy_id == cg_infos[MEMORY_IDX]._hierarchy_id, "/proc/cgroups and /proc/self/cgroup hierarchy mismatch for memory");
        cg_infos[MEMORY_IDX]._cgroup_path = os::strdup(cgroup_path);
      } else if (strcmp(token, "cpuset") == 0) {
        assert(hierarchy_id == cg_infos[CPUSET_IDX]._hierarchy_id, "/proc/cgroups and /proc/self/cgroup hierarchy mismatch for cpuset");
        cg_infos[CPUSET_IDX]._cgroup_path = os::strdup(cgroup_path);
      } else if (strcmp(token, "cpu") == 0) {
        assert(hierarchy_id == cg_infos[CPU_IDX]._hierarchy_id, "/proc/cgroups and /proc/self/cgroup hierarchy mismatch for cpu");
        cg_infos[CPU_IDX]._cgroup_path = os::strdup(cgroup_path);
      } else if (strcmp(token, "cpuacct") == 0) {
        assert(hierarchy_id == cg_infos[CPUACCT_IDX]._hierarchy_id, "/proc/cgroups and /proc/self/cgroup hierarchy mismatch for cpuacct");
        cg_infos[CPUACCT_IDX]._cgroup_path = os::strdup(cgroup_path);
      } else if (strcmp(token, "pids") == 0) {
        assert(hierarchy_id == cg_infos[PIDS_IDX]._hierarchy_id, "/proc/cgroups (%d) and /proc/self/cgroup (%d) hierarchy mismatch for pids",
                                                                 cg_infos[PIDS_IDX]._hierarchy_id, hierarchy_id);
        cg_infos[PIDS_IDX]._cgroup_path = os::strdup(cgroup_path);
      }
    }
    if (cgroups_v2_enabled) {
      // On some systems we have mixed cgroups v1 and cgroups v2 controllers (e.g. freezer on cg1 and
      // all relevant controllers on cg2). Only set the cgroup path when we see a hierarchy id of 0.
      if (hierarchy_id != 0) {
        continue;
      }
      for (int i = 0; i < CG_INFO_LENGTH; i++) {
        assert(cg_infos[i]._cgroup_path == nullptr, "cgroup path must only be set once");
        cg_infos[i]._cgroup_path = os::strdup(cgroup_path);
      }
    }
  }
  fclose(cgroup);

  // Find various mount points by reading /proc/self/mountinfo
  // mountinfo format is documented at https://www.kernel.org/doc/Documentation/filesystems/proc.txt
  mntinfo = os::fopen(proc_self_mountinfo, "r");
  if (mntinfo == nullptr) {
      log_debug(os, container)("Can't open %s, %s",
                               proc_self_mountinfo, os::strerror(errno));
      cleanup(cg_infos);
      *flags = INVALID_CGROUPS_GENERIC;
      return false;
  }

  bool cgroupv2_mount_point_found = false;
  bool any_cgroup_mounts_found = false;
  while ((p = fgets(buf, MAXPATHLEN, mntinfo)) != nullptr) {
    char tmp_fs_type[MAXPATHLEN+1];
    char tmproot[MAXPATHLEN+1];
    char tmpmount[MAXPATHLEN+1];
    char tmpcgroups[MAXPATHLEN+1];
    char mount_opts[MAXPATHLEN+1];
    char *cptr = tmpcgroups;
    char *token;

    /* Cgroup v2 relevant info. We only look for the _mount_path iff cgroups_v2_enabled so
     * as to avoid memory stomping of the _mount_path pointer later on in the cgroup v1
     * block in the hybrid case.
     *
     * We collect the read only mount option in the cgroup infos so as to have that
     * info ready when determining is_containerized().
     */
    if (cgroups_v2_enabled && match_mount_info_line(p,
                                              tmproot,
                                              tmpmount,
                                              mount_opts,
                                              tmp_fs_type,
                                              tmpcgroups /* unused */)) {
      // we likely have an early match return (e.g. cgroup fs match), be sure we have cgroup2 as fstype
      if (strcmp("cgroup2", tmp_fs_type) == 0) {
        cgroupv2_mount_point_found = true;
        any_cgroup_mounts_found = true;
        // For unified we only have a single line with cgroup2 fs type.
        // Therefore use that option for all CG info structs.
        bool ro_option = find_ro_opt(mount_opts);
        for (int i = 0; i < CG_INFO_LENGTH; i++) {
          set_controller_paths(cg_infos, i, "(cg2, unified)", tmpmount, tmproot, ro_option);
        }
      }
    }

    /* Cgroup v1 relevant info
     *
     * Find the cgroup mount point for memory, cpuset, cpu, cpuacct, pids. For each controller
     * determine whether or not they show up as mounted read only or not.
     *
     * Example for docker:
     * 219 214 0:29 /docker/7208cebd00fa5f2e342b1094f7bed87fa25661471a4637118e65f1c995be8a34 /sys/fs/cgroup/memory ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,memory
     *
     * Example for host:
     * 34 28 0:29 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,memory
     *
     * 44 31 0:39 / /sys/fs/cgroup/pids rw,nosuid,nodev,noexec,relatime shared:23 - cgroup cgroup rw,pids
     *
     */
    if (match_mount_info_line(p, tmproot, tmpmount, mount_opts, tmp_fs_type, tmpcgroups)) {
      if (strcmp("cgroup", tmp_fs_type) != 0) {
        // Skip cgroup2 fs lines on hybrid or unified hierarchy.
        continue;
      }
      while ((token = strsep(&cptr, ",")) != nullptr) {
        if (strcmp(token, "memory") == 0) {
          any_cgroup_mounts_found = true;
          bool ro_option = find_ro_opt(mount_opts);
          set_controller_paths(cg_infos, MEMORY_IDX, token, tmpmount, tmproot, ro_option);
          cg_infos[MEMORY_IDX]._data_complete = true;
        } else if (strcmp(token, "cpuset") == 0) {
          any_cgroup_mounts_found = true;
          bool ro_option = find_ro_opt(mount_opts);
          set_controller_paths(cg_infos, CPUSET_IDX, token, tmpmount, tmproot, ro_option);
          cg_infos[CPUSET_IDX]._data_complete = true;
        } else if (strcmp(token, "cpu") == 0) {
          any_cgroup_mounts_found = true;
          bool ro_option = find_ro_opt(mount_opts);
          set_controller_paths(cg_infos, CPU_IDX, token, tmpmount, tmproot, ro_option);
          cg_infos[CPU_IDX]._data_complete = true;
        } else if (strcmp(token, "cpuacct") == 0) {
          any_cgroup_mounts_found = true;
          bool ro_option = find_ro_opt(mount_opts);
          set_controller_paths(cg_infos, CPUACCT_IDX, token, tmpmount, tmproot, ro_option);
          cg_infos[CPUACCT_IDX]._data_complete = true;
        } else if (strcmp(token, "pids") == 0) {
          any_cgroup_mounts_found = true;
          bool ro_option = find_ro_opt(mount_opts);
          set_controller_paths(cg_infos, PIDS_IDX, token, tmpmount, tmproot, ro_option);
          cg_infos[PIDS_IDX]._data_complete = true;
        }
      }
    }
  }
  fclose(mntinfo);

  // Neither cgroup2 nor cgroup filesystems mounted via /proc/self/mountinfo
  // No point in continuing.
  if (!any_cgroup_mounts_found) {
    log_trace(os, container)("No relevant cgroup controllers mounted.");
    cleanup(cg_infos);
    *flags = INVALID_CGROUPS_NO_MOUNT;
    return false;
  }

  if (cgroups_v2_enabled) {
    if (!cgroupv2_mount_point_found) {
      log_trace(os, container)("Mount point for cgroupv2 not found in /proc/self/mountinfo");
      cleanup(cg_infos);
      *flags = INVALID_CGROUPS_V2;
      return false;
    }
    // Cgroups v2 case, we have all the info we need.
    *flags = CGROUPS_V2;
    return true;
  }

  // What follows is cgroups v1
  log_debug(os, container)("Detected cgroups hybrid or legacy hierarchy, using cgroups v1 controllers");

  if (!cg_infos[MEMORY_IDX]._data_complete) {
    log_debug(os, container)("Required cgroup v1 memory subsystem not found");
    cleanup(cg_infos);
    *flags = INVALID_CGROUPS_V1;
    return false;
  }
  if (!cg_infos[CPUSET_IDX]._data_complete) {
    log_debug(os, container)("Required cgroup v1 cpuset subsystem not found");
    cleanup(cg_infos);
    *flags = INVALID_CGROUPS_V1;
    return false;
  }
  if (!cg_infos[CPU_IDX]._data_complete) {
    log_debug(os, container)("Required cgroup v1 cpu subsystem not found");
    cleanup(cg_infos);
    *flags = INVALID_CGROUPS_V1;
    return false;
  }
  if (!cg_infos[CPUACCT_IDX]._data_complete) {
    log_debug(os, container)("Required cgroup v1 cpuacct subsystem not found");
    cleanup(cg_infos);
    *flags = INVALID_CGROUPS_V1;
    return false;
  }
  if (log_is_enabled(Debug, os, container) && !cg_infos[PIDS_IDX]._data_complete) {
    log_debug(os, container)("Optional cgroup v1 pids subsystem not found");
    // keep the other controller info, pids is optional
  }
  // Cgroups v1 case, we have all the info we need.
  *flags = CGROUPS_V1;
  return true;
};

void CgroupSubsystemFactory::cleanup(CgroupInfo* cg_infos) {
  assert(cg_infos != nullptr, "Invariant");
  for (int i = 0; i < CG_INFO_LENGTH; i++) {
    os::free(cg_infos[i]._name);
    os::free(cg_infos[i]._cgroup_path);
    os::free(cg_infos[i]._root_mount_path);
    os::free(cg_infos[i]._mount_path);
  }
}

/* active_processor_count
 *
 * Calculate an appropriate number of active processors for the
 * VM to use based on these three inputs.
 *
 * cpu affinity
 * cgroup cpu quota & cpu period
 * cgroup cpu shares
 *
 * Algorithm:
 *
 * Determine the number of available CPUs from sched_getaffinity
 *
 * If user specified a quota (quota != -1), calculate the number of
 * required CPUs by dividing quota by period.
 *
 * All results of division are rounded up to the next whole number.
 *
 * If quotas have not been specified, return the
 * number of active processors in the system.
 *
 * If quotas have been specified, the resulting number
 * returned will never exceed the number of active processors.
 *
 * return:
 *    number of CPUs
 */
int CgroupSubsystem::active_processor_count() {
  int quota_count = 0;
  int cpu_count;
  int result;

  // We use a cache with a timeout to avoid performing expensive
  // computations in the event this function is called frequently.
  // [See 8227006].
  CachingCgroupController<CgroupCpuController>* contrl = cpu_controller();
  CachedMetric* cpu_limit = contrl->metrics_cache();
  if (!cpu_limit->should_check_metric()) {
    int val = (int)cpu_limit->value();
    log_trace(os, container)("CgroupSubsystem::active_processor_count (cached): %d", val);
    return val;
  }

  cpu_count = os::Linux::active_processor_count();
  result = CgroupUtil::processor_count(contrl->controller(), cpu_count);
  // Update cached metric to avoid re-reading container settings too often
  cpu_limit->set_value(result, OSCONTAINER_CACHE_TIMEOUT);

  return result;
}

/* memory_limit_in_bytes
 *
 * Return the limit of available memory for this process.
 *
 * return:
 *    memory limit in bytes or
 *    -1 for unlimited
 *    OSCONTAINER_ERROR for not supported
 */
jlong CgroupSubsystem::memory_limit_in_bytes() {
  CachingCgroupController<CgroupMemoryController>* contrl = memory_controller();
  CachedMetric* memory_limit = contrl->metrics_cache();
  if (!memory_limit->should_check_metric()) {
    return memory_limit->value();
  }
  jlong phys_mem = os::Linux::physical_memory();
  log_trace(os, container)("total physical memory: " JLONG_FORMAT, phys_mem);
  jlong mem_limit = contrl->controller()->read_memory_limit_in_bytes(phys_mem);
  // Update cached metric to avoid re-reading container settings too often
  memory_limit->set_value(mem_limit, OSCONTAINER_CACHE_TIMEOUT);
  return mem_limit;
}

bool CgroupController::read_string(const char* filename, char* buf, size_t buf_size) {
  assert(buf != nullptr, "buffer must not be null");
  assert(filename != nullptr, "filename must be given");
  const char* s_path = subsystem_path();
  if (s_path == nullptr) {
    log_debug(os, container)("read_string: subsystem path is null");
    return false;
  }

  stringStream file_path;
  file_path.print_raw(s_path);
  file_path.print_raw(filename);

  if (file_path.size() > MAXPATHLEN) {
    log_debug(os, container)("File path too long %s, %s", file_path.base(), filename);
    return false;
  }
  const char* absolute_path = file_path.freeze();
  log_trace(os, container)("Path to %s is %s", filename, absolute_path);

  FILE* fp = os::fopen(absolute_path, "r");
  if (fp == nullptr) {
    log_debug(os, container)("Open of file %s failed, %s", absolute_path, os::strerror(errno));
    return false;
  }

  // Read a single line into the provided buffer.
  // At most buf_size - 1 characters.
  char* line = fgets(buf, buf_size, fp);
  fclose(fp);
  if (line == nullptr) {
    log_debug(os, container)("Empty file %s", absolute_path);
    return false;
  }
  size_t len = strlen(line);
  assert(len <= buf_size - 1, "At most buf_size - 1 bytes can be read");
  if (line[len - 1] == '\n') {
    line[len - 1] = '\0'; // trim trailing new line
  }
  return true;
}

bool CgroupController::read_number(const char* filename, julong* result) {
  char buf[1024];
  bool is_ok = read_string(filename, buf, 1024);
  if (!is_ok) {
    return false;
  }
  int matched = sscanf(buf, JULONG_FORMAT, result);
  if (matched == 1) {
    return true;
  }
  return false;
}

bool CgroupController::read_number_handle_max(const char* filename, jlong* result) {
  char buf[1024];
  bool is_ok = read_string(filename, buf, 1024);
  if (!is_ok) {
    return false;
  }
  jlong val = limit_from_str(buf);
  if (val == OSCONTAINER_ERROR) {
    return false;
  }
  *result = val;
  return true;
}

bool CgroupController::read_numerical_key_value(const char* filename, const char* key, julong* result) {
  assert(key != nullptr, "key must be given");
  assert(result != nullptr, "result pointer must not be null");
  assert(filename != nullptr, "file to search in must be given");
  const char* s_path = subsystem_path();
  if (s_path == nullptr) {
    log_debug(os, container)("read_numerical_key_value: subsystem path is null");
    return false;
  }

  stringStream file_path;
  file_path.print_raw(s_path);
  file_path.print_raw(filename);

  if (file_path.size() > MAXPATHLEN) {
    log_debug(os, container)("File path too long %s, %s", file_path.base(), filename);
    return false;
  }
  const char* absolute_path = file_path.freeze();
  log_trace(os, container)("Path to %s is %s", filename, absolute_path);
  FILE* fp = os::fopen(absolute_path, "r");
  if (fp == nullptr) {
    log_debug(os, container)("Open of file %s failed, %s", absolute_path, os::strerror(errno));
    return false;
  }

  const int buf_len = MAXPATHLEN+1;
  char buf[buf_len];
  char* line = fgets(buf, buf_len, fp);
  bool found_match = false;
  // File consists of multiple lines in a "key value"
  // fashion, we have to find the key.
  const size_t key_len = strlen(key);
  for (; line != nullptr; line = fgets(buf, buf_len, fp)) {
    char after_key = line[key_len];
    if (strncmp(line, key, key_len) == 0
          && isspace((unsigned char) after_key) != 0
          && after_key != '\n') {
      // Skip key, skip space
      const char* value_substr = line + key_len + 1;
      int matched = sscanf(value_substr, JULONG_FORMAT, result);
      found_match = matched == 1;
      if (found_match) {
        break;
      }
    }
  }
  fclose(fp);
  if (found_match) {
    return true;
  }
  log_debug(os, container)("Type %s (key == %s) not found in file %s", JULONG_FORMAT,
                           key, absolute_path);
  return false;
}

bool CgroupController::read_numerical_tuple_value(const char* filename, bool use_first, jlong* result) {
  char buf[1024];
  bool is_ok = read_string(filename, buf, 1024);
  if (!is_ok) {
    return false;
  }
  char token[1024];
  const int matched = sscanf(buf, (use_first ? "%1023s %*s" : "%*s %1023s"), token);
  if (matched != 1) {
    return false;
  }
  jlong val = limit_from_str(token);
  if (val == OSCONTAINER_ERROR) {
    return false;
  }
  *result = val;
  return true;
}

jlong CgroupController::limit_from_str(char* limit_str) {
  if (limit_str == nullptr) {
    return OSCONTAINER_ERROR;
  }
  // Unlimited memory in cgroups is the literal string 'max' for
  // some controllers, for example the pids controller.
  if (strcmp("max", limit_str) == 0) {
    return (jlong)-1;
  }
  julong limit;
  if (sscanf(limit_str, JULONG_FORMAT, &limit) != 1) {
    return OSCONTAINER_ERROR;
  }
  return (jlong)limit;
}

// CgroupSubsystem implementations

jlong CgroupSubsystem::memory_and_swap_limit_in_bytes() {
  julong phys_mem = os::Linux::physical_memory();
  julong host_swap = os::Linux::host_swap();
  return memory_controller()->controller()->memory_and_swap_limit_in_bytes(phys_mem, host_swap);
}

jlong CgroupSubsystem::memory_and_swap_usage_in_bytes() {
  julong phys_mem = os::Linux::physical_memory();
  julong host_swap = os::Linux::host_swap();
  return memory_controller()->controller()->memory_and_swap_usage_in_bytes(phys_mem, host_swap);
}

jlong CgroupSubsystem::memory_soft_limit_in_bytes() {
  julong phys_mem = os::Linux::physical_memory();
  return memory_controller()->controller()->memory_soft_limit_in_bytes(phys_mem);
}

jlong CgroupSubsystem::memory_usage_in_bytes() {
  return memory_controller()->controller()->memory_usage_in_bytes();
}

jlong CgroupSubsystem::memory_max_usage_in_bytes() {
  return memory_controller()->controller()->memory_max_usage_in_bytes();
}

jlong CgroupSubsystem::rss_usage_in_bytes() {
  return memory_controller()->controller()->rss_usage_in_bytes();
}

jlong CgroupSubsystem::cache_usage_in_bytes() {
  return memory_controller()->controller()->cache_usage_in_bytes();
}

int CgroupSubsystem::cpu_quota() {
  return cpu_controller()->controller()->cpu_quota();
}

int CgroupSubsystem::cpu_period() {
  return cpu_controller()->controller()->cpu_period();
}

int CgroupSubsystem::cpu_shares() {
  return cpu_controller()->controller()->cpu_shares();
}

void CgroupSubsystem::print_version_specific_info(outputStream* st) {
  julong phys_mem = os::Linux::physical_memory();
  memory_controller()->controller()->print_version_specific_info(st, phys_mem);
}
