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