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 Nov 8, 2022
1 parent b3593b9 commit 2d9c631
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 189 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
import com.aws.greengrass.lifecyclemanager.Kernel;
import com.aws.greengrass.testcommons.testutilities.GGExtension;
import com.aws.greengrass.testcommons.testutilities.TestUtils;
import com.aws.greengrass.util.platforms.unix.linux.Cgroup;
import com.aws.greengrass.util.platforms.unix.linux.CgroupSubSystem;
import com.aws.greengrass.util.platforms.unix.linux.CGroupV1;
import com.aws.greengrass.util.platforms.unix.linux.LinuxSystemResourceController;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -116,7 +115,7 @@ void GIVEN_LifeCycleEventStreamClient_WHEN_pause_resume_component_THEN_target_se
private LinuxSystemResourceController.CgroupFreezerState getCgroupFreezerState(String serviceName)
throws IOException {
return LinuxSystemResourceController.CgroupFreezerState.valueOf(
new String(Files.readAllBytes(new Cgroup(CgroupSubSystem.Freezer).getCgroupFreezerStateFilePath(serviceName)),
new String(Files.readAllBytes(CGroupV1.Freezer.getCgroupFreezerStateFilePath(serviceName)),
StandardCharsets.UTF_8).trim());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
import com.aws.greengrass.testcommons.testutilities.GGExtension;
import com.aws.greengrass.testcommons.testutilities.NoOpPathOwnershipHandler;
import com.aws.greengrass.util.Pair;
import com.aws.greengrass.util.platforms.unix.linux.Cgroup;
import com.aws.greengrass.util.platforms.unix.linux.CgroupSubSystem;
import com.aws.greengrass.util.platforms.unix.linux.CGroupV1;
import com.aws.greengrass.util.platforms.unix.linux.LinuxSystemResourceController;
import org.apache.commons.lang3.SystemUtils;
import org.junit.jupiter.api.AfterEach;
Expand Down Expand Up @@ -800,11 +799,11 @@ void GIVEN_service_starts_up_WHEN_startup_times_out_THEN_timeout_error_code_pers
}

private void assertResourceLimits(String componentName, long memory, double cpus) throws Exception {
byte[] buf1 = Files.readAllBytes(new Cgroup(CgroupSubSystem.Memory).getComponentMemoryLimitPath(componentName));
byte[] buf1 = Files.readAllBytes(CGroupV1.Memory.getComponentMemoryLimitPath(componentName));
assertThat(memory, equalTo(Long.parseLong(new String(buf1, StandardCharsets.UTF_8).trim())));

byte[] buf2 = Files.readAllBytes(new Cgroup(CgroupSubSystem.CPU).getComponentCpuQuotaPath(componentName));
byte[] buf3 = Files.readAllBytes(new Cgroup(CgroupSubSystem.CPU).getComponentCpuPeriodPath(componentName));
byte[] buf2 = Files.readAllBytes(CGroupV1.CPU.getComponentCpuQuotaPath(componentName));
byte[] buf3 = Files.readAllBytes(CGroupV1.CPU.getComponentCpuPeriodPath(componentName));

int quota = Integer.parseInt(new String(buf2, StandardCharsets.UTF_8).trim());
int period = Integer.parseInt(new String(buf3, StandardCharsets.UTF_8).trim());
Expand Down Expand Up @@ -864,7 +863,7 @@ void GIVEN_running_service_WHEN_pause_resume_requested_THEN_pause_resume_Service
private LinuxSystemResourceController.CgroupFreezerState getCgroupFreezerState(String serviceName)
throws IOException {
return LinuxSystemResourceController.CgroupFreezerState
.valueOf(new String(Files.readAllBytes(new Cgroup(CgroupSubSystem.Freezer).getCgroupFreezerStateFilePath(serviceName))
.valueOf(new String(Files.readAllBytes(CGroupV1.Freezer.getCgroupFreezerStateFilePath(serviceName))
, StandardCharsets.UTF_8).trim());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

@SuppressFBWarnings(value = "DMI_HARDCODED_ABSOLUTE_FILENAME",
justification = "CGroupSubSystemPath virtual filesystem path cannot be relative")
public interface CGroupSubSystemPath {
public interface CGroupSubSystemPaths {
Path CGROUP_ROOT = Paths.get("/sys/fs/cgroup");
String GG_NAMESPACE = "greengrass";
String CGROUP_MEMORY_LIMITS = "memory.limit_in_bytes";
Expand All @@ -45,9 +45,13 @@ default String subsystemMountCmd() {

Path getSubsystemRootPath();

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

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

Path getComponentMemoryLimitPath(String componentName);

Expand All @@ -59,7 +63,9 @@ default Path getComponentCpuQuotaPath(String componentName) {
return null;
}

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

Path getCgroupFreezerStateFilePath(String componentName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
import java.util.Set;

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

private String osString;
private String mountSrc;

CgroupSubSystem(String osString, String mountSrc) {
CGroupV1(String osString, String mountSrc) {
this.osString = osString;
this.mountSrc = mountSrc;
}
Expand Down Expand Up @@ -63,16 +63,6 @@ public Path getSubsystemRootPath() {
return 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);
Expand All @@ -88,11 +78,6 @@ 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
import java.util.Set;

@SuppressFBWarnings(value = "DMI_HARDCODED_ABSOLUTE_FILENAME",
justification = "CgroupSubSystemV2 virtual filesystem path cannot be relative")
public enum CgroupSubSystemV2 implements CGroupSubSystemPath {
justification = "CGroupV2 virtual filesystem path cannot be relative")
public enum CGroupV2 implements CGroupSubSystemPaths {
Memory, CPU, Freezer, Unified;
private static final String CGROUP_SUBTREE_CONTROL_CONTENT = "+cpuset +cpu +io +memory +pids";

Expand All @@ -33,26 +33,11 @@ public Path getSubsystemRootPath() {
return 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);
Expand Down
121 changes: 0 additions & 121 deletions src/main/java/com/aws/greengrass/util/platforms/unix/linux/Cgroup.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ public class LinuxSystemResourceController implements SystemResourceController {
private static final String COMPONENT_NAME = "componentName";
private static final String MEMORY_KEY = "memory";
private static final String CPUS_KEY = "cpus";
private Cgroup memoryCgroup;
private Cgroup cpuCgroup;
private Cgroup freezerCgroup;
private Cgroup unifiedCgroup;
private List<Cgroup> resourceLimitCgroups;
protected CopyOnWriteArrayList<Cgroup> usedCgroups = new CopyOnWriteArrayList<>();
private CGroupSubSystemPaths memoryCgroup;
private CGroupSubSystemPaths cpuCgroup;
private CGroupSubSystemPaths freezerCgroup;
private CGroupSubSystemPaths unifiedCgroup;
private List<CGroupSubSystemPaths> resourceLimitCgroups;
protected CopyOnWriteArrayList<CGroupSubSystemPaths> usedCgroups = new CopyOnWriteArrayList<>();

protected LinuxPlatform platform;

Expand All @@ -55,16 +55,16 @@ public LinuxSystemResourceController(LinuxPlatform platform, boolean isV1Used) {
this.platform = platform;

if (isV1Used) {
this.memoryCgroup = new Cgroup(CgroupSubSystem.Memory);
this.cpuCgroup = new Cgroup(CgroupSubSystem.CPU);
this.freezerCgroup = new Cgroup(CgroupSubSystem.Freezer);
this.memoryCgroup = CGroupV1.Memory;
this.cpuCgroup = CGroupV1.CPU;
this.freezerCgroup = CGroupV1.Freezer;
resourceLimitCgroups = Arrays.asList(
memoryCgroup, cpuCgroup);
} else {
this.unifiedCgroup = new Cgroup(CgroupSubSystemV2.Unified);
this.memoryCgroup = new Cgroup(CgroupSubSystemV2.Memory);
this.cpuCgroup = new Cgroup(CgroupSubSystemV2.CPU);
this.freezerCgroup = new Cgroup(CgroupSubSystemV2.Freezer);
this.unifiedCgroup = CGroupV2.Unified;
this.memoryCgroup = CGroupV2.Memory;
this.cpuCgroup = CGroupV2.CPU;
this.freezerCgroup = CGroupV2.Freezer;
resourceLimitCgroups = Arrays.asList(unifiedCgroup);
}
}
Expand Down Expand Up @@ -129,7 +129,7 @@ protected void updateMemoryResourceLimits(GreengrassService component,

@Override
public void resetResourceLimits(GreengrassService component) {
for (Cgroup cg : resourceLimitCgroups) {
for (CGroupSubSystemPaths cg : resourceLimitCgroups) {
try {
if (Files.exists(cg.getSubsystemComponentPath(component.getServiceName()))) {
Files.delete(cg.getSubsystemComponentPath(component.getServiceName()));
Expand Down Expand Up @@ -178,7 +178,7 @@ public void resumeComponentProcesses(GreengrassService component) throws IOExcep
freezerCgroup.resumeComponentProcesses(component);
}

protected void addComponentProcessToCgroup(String component, Process process, Cgroup cg)
protected void addComponentProcessToCgroup(String component, Process process, CGroupSubSystemPaths cg)
throws IOException {

if (!Files.exists(cg.getSubsystemComponentPath(component))) {
Expand Down Expand Up @@ -227,12 +227,12 @@ private void handleErrorAddingPidToCgroup(IOException e, String component) {
}
}

protected void initializeCgroup(GreengrassService component, Cgroup cgroup) throws IOException {
protected void initializeCgroup(GreengrassService component, CGroupSubSystemPaths cgroup) throws IOException {
cgroup.initializeCgroup(component, platform);
usedCgroups.add(cgroup);
}

private Set<Integer> pidsInComponentCgroup(Cgroup cgroup, String component) throws IOException {
private Set<Integer> pidsInComponentCgroup(CGroupSubSystemPaths cgroup, String component) throws IOException {
return Files.readAllLines(cgroup.getCgroupProcsPath(component))
.stream().map(Integer::parseInt).collect(Collectors.toSet());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ class LinuxSystemResourceControllerV2Test {
@Mock
LinuxPlatform platform;
@Spy
Cgroup cpuCgroup = new Cgroup(CgroupSubSystemV2.CPU);
CGroupSubSystemPaths cpuCgroup = CGroupV2.CPU;
@Spy
Cgroup memoryCgroup = new Cgroup(CgroupSubSystemV2.Memory);
CGroupSubSystemPaths memoryCgroup = CGroupV2.Memory;
@InjectMocks
@Spy
LinuxSystemResourceController linuxSystemResourceControllerV2 = new LinuxSystemResourceController(
Expand Down Expand Up @@ -101,7 +101,7 @@ void GIVEN_cgroupv2_WHEN_cpu_limit_updated_THEN_cpu_limit_file_updated() throws

Files.write(path, "max 100000".getBytes(StandardCharsets.UTF_8));

CGroupSubSystemPath cpuSystemV2 = spy(CgroupSubSystemV2.CPU);
CGroupSubSystemPaths cpuSystemV2 = spy(CGroupV2.CPU);
lenient().when(cpuSystemV2.getComponentCpuMaxPath(COMPONENT_NAME)).thenReturn(path);

cpuSystemV2.handleCpuLimits(component, 0.5);
Expand Down

0 comments on commit 2d9c631

Please sign in to comment.