diff --git a/init/init.cpp b/init/init.cpp index cd0ee58ec..2d9fbbf3e 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -662,6 +662,10 @@ static Result wait_for_coldboot_done_action(const BuiltinArguments& args) } static Result SetupCgroupsAction(const BuiltinArguments&) { + if (!CgroupsAvailable()) { + LOG(INFO) << "Cgroups support in kernel is not enabled"; + return {}; + } // Have to create using make_dir function // for appropriate sepolicy to be set for it make_dir(android::base::Dirname(CGROUPS_RC_PATH), 0711); diff --git a/init/service.cpp b/init/service.cpp index a6330484a..24fcdce75 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -682,24 +682,28 @@ Result Service::Start() { start_order_ = next_start_order_++; process_cgroup_empty_ = false; - bool use_memcg = swappiness_ != -1 || soft_limit_in_bytes_ != -1 || limit_in_bytes_ != -1 || - limit_percent_ != -1 || !limit_property_.empty(); - errno = -createProcessGroup(proc_attr_.uid, pid_, use_memcg); - if (errno != 0) { - if (char byte = 0; write((*pipefd)[1], &byte, 1) < 0) { - return ErrnoError() << "sending notification failed"; + if (CgroupsAvailable()) { + bool use_memcg = swappiness_ != -1 || soft_limit_in_bytes_ != -1 || limit_in_bytes_ != -1 || + limit_percent_ != -1 || !limit_property_.empty(); + errno = -createProcessGroup(proc_attr_.uid, pid_, use_memcg); + if (errno != 0) { + if (char byte = 0; write((*pipefd)[1], &byte, 1) < 0) { + return ErrnoError() << "sending notification failed"; + } + return Error() << "createProcessGroup(" << proc_attr_.uid << ", " << pid_ + << ") failed for service '" << name_ << "'"; } - return Error() << "createProcessGroup(" << proc_attr_.uid << ", " << pid_ - << ") failed for service '" << name_ << "'"; - } - // When the blkio controller is mounted in the v1 hierarchy, NormalIoPriority is - // the default (/dev/blkio). When the blkio controller is mounted in the v2 hierarchy, the - // NormalIoPriority profile has to be applied explicitly. - SetProcessProfiles(proc_attr_.uid, pid_, {"NormalIoPriority"}); + // When the blkio controller is mounted in the v1 hierarchy, NormalIoPriority is + // the default (/dev/blkio). When the blkio controller is mounted in the v2 hierarchy, the + // NormalIoPriority profile has to be applied explicitly. + SetProcessProfiles(proc_attr_.uid, pid_, {"NormalIoPriority"}); - if (use_memcg) { - ConfigureMemcg(); + if (use_memcg) { + ConfigureMemcg(); + } + } else { + process_cgroup_empty_ = true; } if (oom_score_adjust_ != DEFAULT_OOM_SCORE_ADJUST) { diff --git a/init/service_utils.cpp b/init/service_utils.cpp index d19f5eef5..a14969e98 100644 --- a/init/service_utils.cpp +++ b/init/service_utils.cpp @@ -280,6 +280,15 @@ Result SetProcessAttributes(const ProcessAttributes& attr) { } Result WritePidToFiles(std::vector* files) { + if (files->empty()) { + // No files to write pid to, exit early. + return {}; + } + + if (!CgroupsAvailable()) { + return Error() << "cgroups are not available"; + } + // See if there were "writepid" instructions to write to files under cpuset path. std::string cpuset_path; if (CgroupGetControllerPath("cpuset", &cpuset_path)) { diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h index 45a723f74..9b2d77567 100644 --- a/libprocessgroup/include/processgroup/processgroup.h +++ b/libprocessgroup/include/processgroup/processgroup.h @@ -28,6 +28,7 @@ __BEGIN_DECLS static constexpr const char* CGROUPV2_CONTROLLER_NAME = "cgroup2"; +bool CgroupsAvailable(); bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path); bool CgroupGetControllerFromPath(const std::string& path, std::string* cgroup_name); bool CgroupGetAttributePath(const std::string& attr_name, std::string* path); diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp index bdda1020c..3fac373cb 100644 --- a/libprocessgroup/processgroup.cpp +++ b/libprocessgroup/processgroup.cpp @@ -55,6 +55,11 @@ using namespace std::chrono_literals; #define PROCESSGROUP_CGROUP_PROCS_FILE "/cgroup.procs" +bool CgroupsAvailable() { + static bool cgroups_available = access("/proc/cgroups", F_OK) == 0; + return cgroups_available; +} + bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path) { auto controller = CgroupMap::GetInstance().FindController(cgroup_name);