1
2
3
4
5 package oshi.hardware.platform.unix.solaris;
6
7 import static oshi.software.os.unix.solaris.SolarisOperatingSystem.HAS_KSTAT2;
8
9 import java.util.ArrayList;
10 import java.util.Collections;
11 import java.util.Comparator;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Map.Entry;
15 import java.util.stream.Collectors;
16
17 import com.sun.jna.platform.unix.solaris.LibKstat.Kstat;
18 import com.sun.jna.platform.unix.solaris.LibKstat.KstatIO;
19
20 import oshi.annotation.concurrent.ThreadSafe;
21 import oshi.driver.unix.solaris.disk.Iostat;
22 import oshi.driver.unix.solaris.disk.Lshal;
23 import oshi.driver.unix.solaris.disk.Prtvtoc;
24 import oshi.hardware.HWDiskStore;
25 import oshi.hardware.HWPartition;
26 import oshi.hardware.common.AbstractHWDiskStore;
27 import oshi.util.platform.unix.solaris.KstatUtil;
28 import oshi.util.platform.unix.solaris.KstatUtil.KstatChain;
29 import oshi.util.tuples.Quintet;
30
31
32
33
34 @ThreadSafe
35 public final class SolarisHWDiskStore extends AbstractHWDiskStore {
36
37 private long reads = 0L;
38 private long readBytes = 0L;
39 private long writes = 0L;
40 private long writeBytes = 0L;
41 private long currentQueueLength = 0L;
42 private long transferTime = 0L;
43 private long timeStamp = 0L;
44 private List<HWPartition> partitionList;
45
46 private SolarisHWDiskStore(String name, String model, String serial, long size) {
47 super(name, model, serial, size);
48 }
49
50 @Override
51 public long getReads() {
52 return reads;
53 }
54
55 @Override
56 public long getReadBytes() {
57 return readBytes;
58 }
59
60 @Override
61 public long getWrites() {
62 return writes;
63 }
64
65 @Override
66 public long getWriteBytes() {
67 return writeBytes;
68 }
69
70 @Override
71 public long getCurrentQueueLength() {
72 return currentQueueLength;
73 }
74
75 @Override
76 public long getTransferTime() {
77 return transferTime;
78 }
79
80 @Override
81 public long getTimeStamp() {
82 return timeStamp;
83 }
84
85 @Override
86 public List<HWPartition> getPartitions() {
87 return this.partitionList;
88 }
89
90 @Override
91 public boolean updateAttributes() {
92 this.timeStamp = System.currentTimeMillis();
93 if (HAS_KSTAT2) {
94
95 return updateAttributes2();
96 }
97 try (KstatChain kc = KstatUtil.openChain()) {
98 Kstat ksp = kc.lookup(null, 0, getName());
99 if (ksp != null && kc.read(ksp)) {
100 KstatIO data = new KstatIO(ksp.ks_data);
101 this.reads = data.reads;
102 this.writes = data.writes;
103 this.readBytes = data.nread;
104 this.writeBytes = data.nwritten;
105 this.currentQueueLength = (long) data.wcnt + data.rcnt;
106
107 this.transferTime = data.rtime / 1_000_000L;
108 this.timeStamp = ksp.ks_snaptime / 1_000_000L;
109 return true;
110 }
111 }
112 return false;
113 }
114
115 private boolean updateAttributes2() {
116 String fullName = getName();
117 String alpha = fullName;
118 String numeric = "";
119 for (int c = 0; c < fullName.length(); c++) {
120 if (fullName.charAt(c) >= '0' && fullName.charAt(c) <= '9') {
121 alpha = fullName.substring(0, c);
122 numeric = fullName.substring(c);
123 break;
124 }
125 }
126
127 Object[] results = KstatUtil.queryKstat2("kstat:/disk/" + alpha + "/" + getName() + "/0", "reads", "writes",
128 "nread", "nwritten", "wcnt", "rcnt", "rtime", "snaptime");
129
130 if (results[results.length - 1] == null) {
131 results = KstatUtil.queryKstat2("kstat:/disk/" + alpha + "/" + numeric + "/io", "reads", "writes", "nread",
132 "nwritten", "wcnt", "rcnt", "rtime", "snaptime");
133 }
134 if (results[results.length - 1] == null) {
135 return false;
136 }
137 this.reads = results[0] == null ? 0L : (long) results[0];
138 this.writes = results[1] == null ? 0L : (long) results[1];
139 this.readBytes = results[2] == null ? 0L : (long) results[2];
140 this.writeBytes = results[3] == null ? 0L : (long) results[3];
141 this.currentQueueLength = results[4] == null ? 0L : (long) results[4];
142 this.currentQueueLength += results[5] == null ? 0L : (long) results[5];
143
144 this.transferTime = results[6] == null ? 0L : (long) results[6] / 1_000_000L;
145 this.timeStamp = (long) results[7] / 1_000_000L;
146 return true;
147 }
148
149
150
151
152
153
154 public static List<HWDiskStore> getDisks() {
155
156
157 Map<String, String> deviceMap = Iostat.queryPartitionToMountMap();
158
159
160
161
162 Map<String, Integer> majorMap = Lshal.queryDiskToMajorMap();
163
164
165
166 Map<String, Quintet<String, String, String, String, Long>> deviceStringMap = Iostat
167 .queryDeviceStrings(deviceMap.keySet());
168
169 List<HWDiskStore> storeList = new ArrayList<>();
170 for (Entry<String, Quintet<String, String, String, String, Long>> entry : deviceStringMap.entrySet()) {
171 String storeName = entry.getKey();
172 Quintet<String, String, String, String, Long> val = entry.getValue();
173 storeList.add(createStore(storeName, val.getA(), val.getB(), val.getC(), val.getD(), val.getE(),
174 deviceMap.getOrDefault(storeName, ""), majorMap.getOrDefault(storeName, 0)));
175 }
176
177 return storeList;
178 }
179
180 private static SolarisHWDiskStore createStore(String diskName, String model, String vendor, String product,
181 String serial, long size, String mount, int major) {
182 SolarisHWDiskStore store = new SolarisHWDiskStore(diskName,
183 model.isEmpty() ? (vendor + " " + product).trim() : model, serial, size);
184 store.partitionList = Collections.unmodifiableList(Prtvtoc.queryPartitions(mount, major).stream()
185 .sorted(Comparator.comparing(HWPartition::getName)).collect(Collectors.toList()));
186 store.updateAttributes();
187 return store;
188 }
189 }