1
2
3
4
5 package oshi.software.os.unix.aix;
6
7 import static oshi.software.os.OSProcess.State.INVALID;
8 import static oshi.software.os.OSService.State.RUNNING;
9 import static oshi.software.os.OSService.State.STOPPED;
10 import static oshi.util.Memoizer.defaultExpiration;
11 import static oshi.util.Memoizer.memoize;
12
13 import java.io.File;
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Map.Entry;
19 import java.util.Set;
20 import java.util.function.Supplier;
21 import java.util.stream.Collectors;
22
23 import com.sun.jna.Native;
24 import com.sun.jna.platform.unix.aix.Perfstat.perfstat_partition_config_t;
25 import com.sun.jna.platform.unix.aix.Perfstat.perfstat_process_t;
26
27 import oshi.annotation.concurrent.ThreadSafe;
28 import oshi.driver.unix.aix.Uptime;
29 import oshi.driver.unix.aix.Who;
30 import oshi.driver.unix.aix.perfstat.PerfstatConfig;
31 import oshi.driver.unix.aix.perfstat.PerfstatProcess;
32 import oshi.jna.platform.unix.AixLibc;
33 import oshi.software.common.AbstractOperatingSystem;
34 import oshi.software.os.FileSystem;
35 import oshi.software.os.InternetProtocolStats;
36 import oshi.software.os.NetworkParams;
37 import oshi.software.os.OSProcess;
38 import oshi.software.os.OSService;
39 import oshi.software.os.OSThread;
40 import oshi.util.ExecutingCommand;
41 import oshi.util.ParseUtil;
42 import oshi.util.Util;
43 import oshi.util.tuples.Pair;
44
45
46
47
48
49 @ThreadSafe
50 public class AixOperatingSystem extends AbstractOperatingSystem {
51
52 private final Supplier<perfstat_partition_config_t> config = memoize(PerfstatConfig::queryConfig);
53 private final Supplier<perfstat_process_t[]> procCpu = memoize(PerfstatProcess::queryProcesses,
54 defaultExpiration());
55
56 private static final long BOOTTIME = querySystemBootTimeMillis() / 1000L;
57
58 @Override
59 public String queryManufacturer() {
60 return "IBM";
61 }
62
63 @Override
64 public Pair<String, OSVersionInfo> queryFamilyVersionInfo() {
65 perfstat_partition_config_t cfg = config.get();
66
67 String systemName = System.getProperty("os.name");
68 String archName = System.getProperty("os.arch");
69 String versionNumber = System.getProperty("os.version");
70 if (Util.isBlank(versionNumber)) {
71 versionNumber = ExecutingCommand.getFirstAnswer("oslevel");
72 }
73 String releaseNumber = Native.toString(cfg.OSBuild);
74 if (Util.isBlank(releaseNumber)) {
75 releaseNumber = ExecutingCommand.getFirstAnswer("oslevel -s");
76 } else {
77
78 int idx = releaseNumber.lastIndexOf(' ');
79 if (idx > 0 && idx < releaseNumber.length()) {
80 releaseNumber = releaseNumber.substring(idx + 1);
81 }
82 }
83 return new Pair<>(systemName, new OSVersionInfo(versionNumber, archName, releaseNumber));
84 }
85
86 @Override
87 protected int queryBitness(int jvmBitness) {
88 if (jvmBitness == 64) {
89 return 64;
90 }
91
92 return (config.get().conf & 0x0080_0000) > 0 ? 64 : 32;
93 }
94
95 @Override
96 public FileSystem getFileSystem() {
97 return new AixFileSystem();
98 }
99
100 @Override
101 public InternetProtocolStats getInternetProtocolStats() {
102 return new AixInternetProtocolStats();
103 }
104
105 @Override
106 public List<OSProcess> queryAllProcesses() {
107 return getProcessListFromProcfs(-1);
108 }
109
110 @Override
111 public List<OSProcess> queryChildProcesses(int parentPid) {
112 List<OSProcess> allProcs = queryAllProcesses();
113 Set<Integer> descendantPids = getChildrenOrDescendants(allProcs, parentPid, false);
114 return allProcs.stream().filter(p -> descendantPids.contains(p.getProcessID())).collect(Collectors.toList());
115 }
116
117 @Override
118 public List<OSProcess> queryDescendantProcesses(int parentPid) {
119 List<OSProcess> allProcs = queryAllProcesses();
120 Set<Integer> descendantPids = getChildrenOrDescendants(allProcs, parentPid, true);
121 return allProcs.stream().filter(p -> descendantPids.contains(p.getProcessID())).collect(Collectors.toList());
122 }
123
124 @Override
125 public OSProcess getProcess(int pid) {
126 List<OSProcess> procs = getProcessListFromProcfs(pid);
127 if (procs.isEmpty()) {
128 return null;
129 }
130 return procs.get(0);
131 }
132
133 private List<OSProcess> getProcessListFromProcfs(int pid) {
134 List<OSProcess> procs = new ArrayList<>();
135
136 perfstat_process_t[] perfstat = procCpu.get();
137 Map<Integer, Pair<Long, Long>> cpuMap = new HashMap<>();
138 for (perfstat_process_t stat : perfstat) {
139 int statpid = (int) stat.pid;
140 if (pid < 0 || statpid == pid) {
141 cpuMap.put(statpid, new Pair<>((long) stat.ucpu_time, (long) stat.scpu_time));
142 }
143 }
144
145
146 for (Entry<Integer, Pair<Long, Long>> entry : cpuMap.entrySet()) {
147 OSProcess proc = new AixOSProcess(entry.getKey(), entry.getValue(), procCpu, this);
148 if (proc.getState() != INVALID) {
149 procs.add(proc);
150 }
151 }
152 return procs;
153 }
154
155 @Override
156 public int getProcessId() {
157 return AixLibc.INSTANCE.getpid();
158 }
159
160 @Override
161 public int getProcessCount() {
162 return procCpu.get().length;
163 }
164
165 @Override
166 public int getThreadId() {
167 return AixLibc.INSTANCE.thread_self();
168 }
169
170 @Override
171 public OSThread getCurrentThread() {
172 OSProcess proc = getCurrentProcess();
173 final int tid = getThreadId();
174 return proc.getThreadDetails().stream().filter(t -> t.getThreadId() == tid).findFirst()
175 .orElse(new AixOSThread(proc.getProcessID(), tid));
176 }
177
178 @Override
179 public int getThreadCount() {
180 long tc = 0L;
181 for (perfstat_process_t proc : procCpu.get()) {
182 tc += proc.num_threads;
183 }
184 return (int) tc;
185 }
186
187 @Override
188 public long getSystemUptime() {
189 return System.currentTimeMillis() / 1000L - BOOTTIME;
190 }
191
192 @Override
193 public long getSystemBootTime() {
194 return BOOTTIME;
195 }
196
197 private static long querySystemBootTimeMillis() {
198 long bootTime = Who.queryBootTime();
199 if (bootTime >= 1000L) {
200 return bootTime;
201 }
202 return System.currentTimeMillis() - Uptime.queryUpTime();
203 }
204
205 @Override
206 public NetworkParams getNetworkParams() {
207 return new AixNetworkParams();
208 }
209
210 @Override
211 public List<OSService> getServices() {
212 List<OSService> services = new ArrayList<>();
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227 List<String> systemServicesInfoList = ExecutingCommand.runNative("lssrc -a");
228 if (systemServicesInfoList.size() > 1) {
229 systemServicesInfoList.remove(0);
230 for (String systemService : systemServicesInfoList) {
231 String[] serviceSplit = ParseUtil.whitespaces.split(systemService.trim());
232 if (systemService.contains("active")) {
233 if (serviceSplit.length == 4) {
234 services.add(new OSService(serviceSplit[0], ParseUtil.parseIntOrDefault(serviceSplit[2], 0),
235 RUNNING));
236 } else if (serviceSplit.length == 3) {
237 services.add(new OSService(serviceSplit[0], ParseUtil.parseIntOrDefault(serviceSplit[1], 0),
238 RUNNING));
239 }
240 } else if (systemService.contains("inoperative")) {
241 services.add(new OSService(serviceSplit[0], 0, STOPPED));
242 }
243 }
244 }
245
246 File dir = new File("/etc/rc.d/init.d");
247 File[] listFiles;
248 if (dir.exists() && dir.isDirectory() && (listFiles = dir.listFiles()) != null) {
249 for (File file : listFiles) {
250 String installedService = ExecutingCommand.getFirstAnswer(file.getAbsolutePath() + " status");
251
252 if (installedService.contains("running")) {
253 services.add(new OSService(file.getName(), ParseUtil.parseLastInt(installedService, 0), RUNNING));
254 } else {
255 services.add(new OSService(file.getName(), 0, STOPPED));
256 }
257 }
258 }
259 return services;
260 }
261 }