/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.jstorm.container.cgroup.core; import java.io.IOException; import java.util.List; import com.alibaba.jstorm.container.CgroupUtils; import com.alibaba.jstorm.container.Constants; import com.alibaba.jstorm.container.SubSystemType; import com.alibaba.jstorm.container.cgroup.Device; public class DevicesCore implements CgroupCore { private final String dir; public static final String DEVICES_ALLOW = "/devices.allow"; public static final String DEVICES_DENY = "/devices.deny"; public static final String DEVICES_LIST = "/devices.list"; public static final char TYPE_ALL = 'a'; public static final char TYPE_BLOCK = 'b'; public static final char TYPE_CHAR = 'c'; public static final int ACCESS_READ = 1; public static final int ACCESS_WRITE = 2; public static final int ACCESS_CREATE = 4; public static final char ACCESS_READ_CH = 'r'; public static final char ACCESS_WRITE_CH = 'w'; public static final char ACCESS_CREATE_CH = 'm'; public DevicesCore(String dir) { this.dir = dir; } @Override public SubSystemType getType() { // TODO Auto-generated method stub return SubSystemType.devices; } public static class Record { Device device; char type; int accesses; public Record(char type, Device device, int accesses) { this.type = type; this.device = device; this.accesses = accesses; } public Record(String output) { if (output.contains("*")) { System.out.println("Pre:" + output); output = output.replaceAll("\\*", "-1"); System.out.println("After:" + output); } String[] splits = output.split("[: ]"); type = splits[0].charAt(0); int major = Integer.parseInt(splits[1]); int minor = Integer.parseInt(splits[2]); device = new Device(major, minor); accesses = 0; for (char c : splits[3].toCharArray()) { if (c == ACCESS_READ_CH) { accesses |= ACCESS_READ; } if (c == ACCESS_CREATE_CH) { accesses |= ACCESS_CREATE; } if (c == ACCESS_WRITE_CH) { accesses |= ACCESS_WRITE; } } } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(type); sb.append(' '); sb.append(device.major); sb.append(':'); sb.append(device.minor); sb.append(' '); sb.append(getAccessesFlag(accesses)); return sb.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + accesses; result = prime * result + ((device == null) ? 0 : device.hashCode()); result = prime * result + type; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Record other = (Record) obj; if (accesses != other.accesses) return false; if (device == null) { if (other.device != null) return false; } else if (!device.equals(other.device)) return false; if (type != other.type) return false; return true; } public static Record[] parseRecordList(List<String> output) { Record[] records = new Record[output.size()]; for (int i = 0, l = output.size(); i < l; i++) { records[i] = new Record(output.get(i)); } return records; } public static StringBuilder getAccessesFlag(int accesses) { StringBuilder sb = new StringBuilder(); if ((accesses & ACCESS_READ) != 0) { sb.append(ACCESS_READ_CH); } if ((accesses & ACCESS_WRITE) != 0) { sb.append(ACCESS_WRITE_CH); } if ((accesses & ACCESS_CREATE) != 0) { sb.append(ACCESS_CREATE_CH); } return sb; } } private void setPermission(String prop, char type, Device device, int accesses) throws IOException { Record record = new Record(type, device, accesses); CgroupUtils.writeFileByLine(Constants.getDir(this.dir, prop), record.toString()); } public void setAllow(char type, Device device, int accesses) throws IOException { setPermission(DEVICES_ALLOW, type, device, accesses); } public void setDeny(char type, Device device, int accesses) throws IOException { setPermission(DEVICES_DENY, type, device, accesses); } public Record[] getList() throws IOException { List<String> output = CgroupUtils.readFileByLine(Constants.getDir(this.dir, DEVICES_LIST)); return Record.parseRecordList(output); } }