1
2
3
4
5 package oshi.hardware.platform.unix.openbsd;
6
7 import static oshi.util.Memoizer.defaultExpiration;
8 import static oshi.util.Memoizer.memoize;
9
10 import java.util.ArrayList;
11 import java.util.List;
12 import java.util.function.Supplier;
13 import java.util.regex.Matcher;
14 import java.util.regex.Pattern;
15
16 import oshi.annotation.concurrent.ThreadSafe;
17 import oshi.driver.unix.openbsd.disk.Disklabel;
18 import oshi.hardware.HWDiskStore;
19 import oshi.hardware.HWPartition;
20 import oshi.hardware.common.AbstractHWDiskStore;
21 import oshi.util.ExecutingCommand;
22 import oshi.util.ParseUtil;
23 import oshi.util.platform.unix.openbsd.OpenBsdSysctlUtil;
24 import oshi.util.tuples.Quartet;
25
26
27
28
29 @ThreadSafe
30 public final class OpenBsdHWDiskStore extends AbstractHWDiskStore {
31
32 private final Supplier<List<String>> iostat = memoize(OpenBsdHWDiskStore::querySystatIostat, defaultExpiration());
33
34 private long reads = 0L;
35 private long readBytes = 0L;
36 private long writes = 0L;
37 private long writeBytes = 0L;
38 private long currentQueueLength = 0L;
39 private long transferTime = 0L;
40 private long timeStamp = 0L;
41 private List<HWPartition> partitionList;
42
43 private OpenBsdHWDiskStore(String name, String model, String serial, long size) {
44 super(name, model, serial, size);
45 }
46
47
48
49
50
51
52 public static List<HWDiskStore> getDisks() {
53 List<HWDiskStore> diskList = new ArrayList<>();
54 List<String> dmesg = null;
55
56
57
58 String[] devices = OpenBsdSysctlUtil.sysctl("hw.disknames", "").split(",");
59 OpenBsdHWDiskStore store;
60 String diskName;
61 for (String device : devices) {
62 diskName = device.split(":")[0];
63
64 Quartet<String, String, Long, List<HWPartition>> diskdata = Disklabel.getDiskParams(diskName);
65 String model = diskdata.getA();
66 long size = diskdata.getC();
67 if (size <= 1) {
68 if (dmesg == null) {
69 dmesg = ExecutingCommand.runNative("dmesg");
70 }
71 Pattern diskAt = Pattern.compile(diskName + " at .*<(.+)>.*");
72 Pattern diskMB = Pattern
73 .compile(diskName + ":.* (\\d+)MB, (?:(\\d+) bytes\\/sector, )?(?:(\\d+) sectors).*");
74 for (String line : dmesg) {
75 Matcher m = diskAt.matcher(line);
76 if (m.matches()) {
77 model = m.group(1);
78 }
79 m = diskMB.matcher(line);
80 if (m.matches()) {
81
82 long sectors = ParseUtil.parseLongOrDefault(m.group(3), 0L);
83
84 long bytesPerSector = ParseUtil.parseLongOrDefault(m.group(2), 0L);
85 if (bytesPerSector == 0 && sectors > 0) {
86
87
88
89 size = ParseUtil.parseLongOrDefault(m.group(1), 0L) << 20;
90
91 bytesPerSector = size / sectors;
92
93 bytesPerSector = Long.highestOneBit(bytesPerSector + bytesPerSector >> 1);
94 }
95 size = bytesPerSector * sectors;
96 break;
97 }
98 }
99 }
100 store = new OpenBsdHWDiskStore(diskName, model, diskdata.getB(), size);
101 store.partitionList = diskdata.getD();
102 store.updateAttributes();
103
104 diskList.add(store);
105 }
106 return diskList;
107 }
108
109 @Override
110 public long getReads() {
111 return reads;
112 }
113
114 @Override
115 public long getReadBytes() {
116 return readBytes;
117 }
118
119 @Override
120 public long getWrites() {
121 return writes;
122 }
123
124 @Override
125 public long getWriteBytes() {
126 return writeBytes;
127 }
128
129 @Override
130 public long getCurrentQueueLength() {
131 return currentQueueLength;
132 }
133
134 @Override
135 public long getTransferTime() {
136 return transferTime;
137 }
138
139 @Override
140 public long getTimeStamp() {
141 return timeStamp;
142 }
143
144 @Override
145 public List<HWPartition> getPartitions() {
146 return this.partitionList;
147 }
148
149 @Override
150 public boolean updateAttributes() {
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 long now = System.currentTimeMillis();
174 boolean diskFound = false;
175 for (String line : iostat.get()) {
176 String[] split = ParseUtil.whitespaces.split(line);
177 if (split.length < 7 && split[0].equals(getName())) {
178 diskFound = true;
179 this.readBytes = ParseUtil.parseMultipliedToLongs(split[1]);
180 this.writeBytes = ParseUtil.parseMultipliedToLongs(split[2]);
181 this.reads = (long) ParseUtil.parseDoubleOrDefault(split[3], 0d);
182 this.writes = (long) ParseUtil.parseDoubleOrDefault(split[4], 0d);
183
184 this.transferTime = (long) (ParseUtil.parseDoubleOrDefault(split[5], 0d) * 1000);
185 this.timeStamp = now;
186 }
187 }
188 return diskFound;
189 }
190
191 private static List<String> querySystatIostat() {
192 return ExecutingCommand.runNative("systat -ab iostat");
193 }
194 }