Skip to content

Commit

Permalink
feat: linux control group version 2 API support cgroup v2
Browse files Browse the repository at this point in the history
  • Loading branch information
ChangxinDong committed Oct 21, 2022
1 parent 271016f commit a285b4b
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 96 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package com.aws.greengrass.util.platforms.unix.linux;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

import java.nio.file.Path;
import java.nio.file.Paths;

@SuppressFBWarnings(value = "DMI_HARDCODED_ABSOLUTE_FILENAME",
justification = "CGroupSubSystemPath virtual filesystem path cannot be relative")
public interface CGroupSubSystemPath {
String CGROUP_ROOT = "/sys/fs/cgroup";
String GG_NAMESPACE = "greengrass";
String CGROUP_MEMORY_LIMITS = "memory.limit_in_bytes";
String CPU_CFS_PERIOD_US = "cpu.cfs_period_us";
String CPU_CFS_QUOTA_US = "cpu.cfs_quota_us";
String CGROUP_PROCS = "cgroup.procs";
String FREEZER_STATE_FILE = "freezer.state";
String CPU_MAX = "cpu.max";
String MEMORY_MAX = "memory.max";
String CGROUP_SUBTREE_CONTROL = "cgroup.subtree_control";
String CGROUP_FREEZE = "cgroup.freeze";

default Path getRootPath() {
return Paths.get(CGROUP_ROOT);
}

String rootMountCmd();

default String subsystemMountCmd() {
return null;
}

Path getSubsystemRootPath();

Path getSubsystemGGPath();

Path getSubsystemComponentPath(String componentName);

Path getComponentMemoryLimitPath(String componentName);

default Path getComponentCpuPeriodPath(String componentName) {
return null;
}

default Path getComponentCpuQuotaPath(String componentName) {
return null;
}

Path getCgroupProcsPath(String componentName);

Path getCgroupFreezerStateFilePath(String componentName);

default Path getRootSubTreeControlPath() {
return null;
}

default Path getGGSubTreeControlPath() {
return null;
}

default Path getComponentCpuMaxPath(String componentName) {
return null;
}

default Path getCgroupFreezePath(String componentName) {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,54 +5,20 @@

package com.aws.greengrass.util.platforms.unix.linux;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.commons.lang3.StringUtils;

import java.nio.file.Path;
import java.nio.file.Paths;

/**
* Represents Linux cgroup subsystems.
*/
@SuppressFBWarnings(value = "DMI_HARDCODED_ABSOLUTE_FILENAME", justification = "Cgroup virtual filesystem path "
+ "cannot be relative")
public class Cgroup {
private static final String CGROUP_ROOT = "/sys/fs/cgroup";
private static final String GG_NAMESPACE = "greengrass";
private static final String CGROUP_MEMORY_LIMITS = "memory.limit_in_bytes";
private static final String CPU_CFS_PERIOD_US = "cpu.cfs_period_us";
private static final String CPU_CFS_QUOTA_US = "cpu.cfs_quota_us";
private static final String CGROUP_PROCS = "cgroup.procs";
private static final String FREEZER_STATE_FILE = "freezer.state";
private static final String CPU_MAX = "cpu.max";
private static final String MEMORY_MAX = "memory.max";
private static final String CGROUP_SUBTREE_CONTROL = "cgroup.subtree_control";
private static final String CGROUP_FREEZE = "cgroup.freeze";

private final String osString;
private final String mountSrc;

/**
* Cgroup constructor.
*
* @param subSystem subController
*/
public Cgroup(CgroupSubSystem subSystem) {
this.osString = subSystem.getOsString();
this.mountSrc = subSystem.getMountSrc();
}
private final CGroupSubSystemPath subSystem;

/**
* Cgroup constructor.
* @param subSystemV2 subsystem version2
*/
public Cgroup(CgroupSubSystemV2 subSystemV2) {
this.osString = subSystemV2.getOsString();
this.mountSrc = subSystemV2.getMountSrc();
public Cgroup(CGroupSubSystemPath subSystem) {
this.subSystem = subSystem;
}

public static Path getRootPath() {
return Paths.get(CGROUP_ROOT);
public Path getRootPath() {
return subSystem.getRootPath();
}

/**
Expand All @@ -61,27 +27,23 @@ public static Path getRootPath() {
* @return mount command string
*/
public String rootMountCmd() {
if (StringUtils.isEmpty(osString)) {
return String.format("mount -t cgroup2 none %s", CGROUP_ROOT);
} else {
return String.format("mount -t tmpfs cgroup %s", CGROUP_ROOT);
}
return subSystem.rootMountCmd();
}

public String subsystemMountCmd() {
return String.format("mount -t cgroup -o %s %s %s", osString, mountSrc, getSubsystemRootPath());
return subSystem.subsystemMountCmd();
}

public Path getSubsystemRootPath() {
return Paths.get(CGROUP_ROOT).resolve(osString);
return subSystem.getSubsystemRootPath();
}

public Path getSubsystemGGPath() {
return getSubsystemRootPath().resolve(GG_NAMESPACE);
return subSystem.getSubsystemGGPath();
}

public Path getSubsystemComponentPath(String componentName) {
return getSubsystemGGPath().resolve(componentName);
return subSystem.getSubsystemComponentPath(componentName);
}

/**
Expand All @@ -91,23 +53,19 @@ public Path getSubsystemComponentPath(String componentName) {
* @return memory limit Path
*/
public Path getComponentMemoryLimitPath(String componentName) {
if (StringUtils.isEmpty(osString)) {
return getSubsystemComponentPath(componentName).resolve(MEMORY_MAX);
} else {
return getSubsystemComponentPath(componentName).resolve(CGROUP_MEMORY_LIMITS);
}
return subSystem.getComponentMemoryLimitPath(componentName);
}

public Path getComponentCpuPeriodPath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CPU_CFS_PERIOD_US);
return subSystem.getComponentCpuPeriodPath(componentName);
}

public Path getComponentCpuQuotaPath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CPU_CFS_QUOTA_US);
return subSystem.getComponentCpuQuotaPath(componentName);
}

public Path getCgroupProcsPath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CGROUP_PROCS);
return subSystem.getCgroupProcsPath(componentName);
}

/**
Expand All @@ -117,27 +75,23 @@ public Path getCgroupProcsPath(String componentName) {
* @return cgroup freezer path
*/
public Path getCgroupFreezerStateFilePath(String componentName) {
if (StringUtils.isEmpty(osString)) {
return getSubsystemComponentPath(componentName).resolve(CGROUP_FREEZE);
} else {
return getSubsystemComponentPath(componentName).resolve(FREEZER_STATE_FILE);
}
return subSystem.getCgroupFreezerStateFilePath(componentName);
}

public Path getRootSubTreeControlPath() {
return getSubsystemRootPath().resolve(CGROUP_SUBTREE_CONTROL);
return subSystem.getRootSubTreeControlPath();
}

public Path getGGSubTreeControlPath() {
return getSubsystemGGPath().resolve(CGROUP_SUBTREE_CONTROL);
return subSystem.getGGSubTreeControlPath();
}

public Path getComponentCpuMaxPath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CPU_MAX);
return subSystem.getComponentCpuMaxPath(componentName);
}

public Path getCgroupFreezePath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CGROUP_FREEZE);
return subSystem.getCgroupFreezePath(componentName);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@

package com.aws.greengrass.util.platforms.unix.linux;

public enum CgroupSubSystem {
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

import java.nio.file.Path;
import java.nio.file.Paths;

@SuppressFBWarnings(value = "DMI_HARDCODED_ABSOLUTE_FILENAME",
justification = "CgroupSubSystem virtual filesystem path cannot be relative")
public enum CgroupSubSystem implements CGroupSubSystemPath {
Memory("memory", ""), CPU("cpu,cpuacct", ""), Freezer("freezer", "freezer");

private String osString;
Expand Down Expand Up @@ -33,4 +40,54 @@ public String getOsString() {
public String getMountSrc() {
return mountSrc;
}

@Override
public String rootMountCmd() {
return String.format("mount -t tmpfs cgroup %s", CGROUP_ROOT);
}

@Override
public String subsystemMountCmd() {
return String.format("mount -t cgroup -o %s %s %s", osString, mountSrc, getSubsystemRootPath());
}

@Override
public Path getSubsystemRootPath() {
return Paths.get(CGROUP_ROOT).resolve(osString);
}

@Override
public Path getSubsystemGGPath() {
return getSubsystemRootPath().resolve(GG_NAMESPACE);
}

@Override
public Path getSubsystemComponentPath(String componentName) {
return getSubsystemGGPath().resolve(componentName);
}

@Override
public Path getComponentMemoryLimitPath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CGROUP_MEMORY_LIMITS);
}

@Override
public Path getComponentCpuPeriodPath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CPU_CFS_PERIOD_US);
}

@Override
public Path getComponentCpuQuotaPath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CPU_CFS_QUOTA_US);
}

@Override
public Path getCgroupProcsPath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CGROUP_PROCS);
}

@Override
public Path getCgroupFreezerStateFilePath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(FREEZER_STATE_FILE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,68 @@

package com.aws.greengrass.util.platforms.unix.linux;

public enum CgroupSubSystemV2 {
Memory("", ""), CPU("", ""), Freezer("", ""),
Unified("","");

private String osString;
private String mountSrc;

CgroupSubSystemV2(String osString, String mountSrc) {
this.osString = osString;
this.mountSrc = mountSrc;
}

/**
* Get the osString associated with this CgroupSubController.
*
* @return the osString associated with this CgroupSubController.
*/
public String getOsString() {
return osString;
}

/**
* Get the mountSrc associated with this CgroupSubController.
*
* @return the mountSrc associated with this CgroupSubController.
*/
public String getMountSrc() {
return mountSrc;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

import java.nio.file.Path;
import java.nio.file.Paths;

@SuppressFBWarnings(value = "DMI_HARDCODED_ABSOLUTE_FILENAME",
justification = "CgroupSubSystemV2 virtual filesystem path cannot be relative")
public enum CgroupSubSystemV2 implements CGroupSubSystemPath {
Memory, CPU, Freezer, Unified;

@Override
public String rootMountCmd() {
return String.format("mount -t cgroup2 none %s", CGROUP_ROOT);
}

@Override
public Path getSubsystemRootPath() {
return Paths.get(CGROUP_ROOT);
}

@Override
public Path getSubsystemGGPath() {
return getSubsystemRootPath().resolve(GG_NAMESPACE);
}

@Override
public Path getSubsystemComponentPath(String componentName) {
return getSubsystemGGPath().resolve(componentName);
}

@Override
public Path getComponentMemoryLimitPath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(MEMORY_MAX);
}

@Override
public Path getCgroupProcsPath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CGROUP_PROCS);
}

@Override
public Path getCgroupFreezerStateFilePath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CGROUP_FREEZE);
}

@Override
public Path getRootSubTreeControlPath() {
return getSubsystemRootPath().resolve(CGROUP_SUBTREE_CONTROL);
}

@Override
public Path getGGSubTreeControlPath() {
return getSubsystemGGPath().resolve(CGROUP_SUBTREE_CONTROL);
}

@Override
public Path getComponentCpuMaxPath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CPU_MAX);
}

@Override
public Path getCgroupFreezePath(String componentName) {
return getSubsystemComponentPath(componentName).resolve(CGROUP_FREEZE);
}
}
Loading

0 comments on commit a285b4b

Please sign in to comment.