package org.act.tstream.daemon.supervisor;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.act.tstream.client.ConfigExtension;
import org.act.tstream.container.CgroupCenter;
import org.act.tstream.container.Hierarchy;
import org.act.tstream.container.SubSystemType;
import org.act.tstream.container.SystemOperation;
import org.act.tstream.container.cgroup.CgroupCommon;
import org.act.tstream.utils.JStormUtils;
import org.act.tstream.container.cgroup.core.CgroupCore;
import org.act.tstream.container.cgroup.core.CpuCore;
public class CgroupManager {
public static final Logger LOG = Logger.getLogger(CgroupManager.class);
public static final String JSTORM_HIERARCHY_NAME = "jstorm_cpu";
public static final int ONE_CPU_SLOT = 1024;
private CgroupCenter center;
private Hierarchy h;
private CgroupCommon rootCgroup;
private static final String JSTORM_CPU_HIERARCHY_DIR = "/cgroup/cpu";
private static String root_dir;
public CgroupManager(Map conf) {
LOG.info("running on cgroup mode");
// Cgconfig service is used to create the corresponding cpu hierarchy "/cgroup/cpu"
root_dir = ConfigExtension.getCgroupRootDir(conf);
if(root_dir == null)
throw new RuntimeException(
"Check configuration file. The supervisor.cgroup.rootdir is missing.");
File file = new File(JSTORM_CPU_HIERARCHY_DIR + "/" + root_dir);
if(!file.exists()) {
LOG.error(JSTORM_CPU_HIERARCHY_DIR + "/" + root_dir + " is not existing.");
throw new RuntimeException(
"Check if cgconfig service starts or /etc/cgconfig.conf is consistent with configuration file.");
}
center = CgroupCenter.getInstance();
if (center == null)
throw new RuntimeException(
"Cgroup error, please check /proc/cgroups");
this.prepareSubSystem();
}
public String startNewWorker(int cpuNum, String workerId)
throws SecurityException, IOException {
CgroupCommon workerGroup = new CgroupCommon(workerId, h,
this.rootCgroup);
this.center.create(workerGroup);
CgroupCore cpu = workerGroup.getCores().get(SubSystemType.cpu);
CpuCore cpuCore = (CpuCore) cpu;
cpuCore.setCpuShares(cpuNum * ONE_CPU_SLOT);
StringBuilder sb = new StringBuilder();
sb.append("cgexec -g cpu:").append(workerGroup.getName()).append(" ");
return sb.toString();
}
public void shutDownWorker(String workerId, boolean isKilled) {
CgroupCommon workerGroup = new CgroupCommon(workerId, h,
this.rootCgroup);
try {
if (isKilled == false) {
for (Integer pid : workerGroup.getTasks()) {
JStormUtils.kill(pid);
}
JStormUtils.sleepMs(1500);
}
center.delete(workerGroup);
}catch(Exception e) {
LOG.info("No task of " + workerId);
}
}
public void close() throws IOException {
this.center.delete(this.rootCgroup);
}
private void prepareSubSystem() {
h = center.busy(SubSystemType.cpu);
if (h == null) {
Set<SubSystemType> types = new HashSet<SubSystemType>();
types.add(SubSystemType.cpu);
h = new Hierarchy(JSTORM_HIERARCHY_NAME, types,JSTORM_CPU_HIERARCHY_DIR);
}
rootCgroup = new CgroupCommon(root_dir, h, h.getRootCgroups());
}
}