1
2
3
4
5 package oshi.hardware.platform.unix.aix;
6
7 import java.util.ArrayList;
8 import java.util.Comparator;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.function.Supplier;
12 import java.util.stream.Collectors;
13
14 import com.sun.jna.Native;
15 import com.sun.jna.platform.unix.aix.Perfstat.perfstat_disk_t;
16
17 import oshi.annotation.concurrent.ThreadSafe;
18 import oshi.driver.unix.aix.Ls;
19 import oshi.driver.unix.aix.Lscfg;
20 import oshi.driver.unix.aix.Lspv;
21 import oshi.hardware.HWDiskStore;
22 import oshi.hardware.HWPartition;
23 import oshi.hardware.common.AbstractHWDiskStore;
24 import oshi.util.Constants;
25 import oshi.util.tuples.Pair;
26
27
28
29
30 @ThreadSafe
31 public final class AixHWDiskStore extends AbstractHWDiskStore {
32
33 private final Supplier<perfstat_disk_t[]> diskStats;
34
35 private long reads = 0L;
36 private long readBytes = 0L;
37 private long writes = 0L;
38 private long writeBytes = 0L;
39 private long currentQueueLength = 0L;
40 private long transferTime = 0L;
41 private long timeStamp = 0L;
42 private List<HWPartition> partitionList;
43
44 private AixHWDiskStore(String name, String model, String serial, long size, Supplier<perfstat_disk_t[]> diskStats) {
45 super(name, model, serial, size);
46 this.diskStats = diskStats;
47 }
48
49 @Override
50 public synchronized long getReads() {
51 return reads;
52 }
53
54 @Override
55 public synchronized long getReadBytes() {
56 return readBytes;
57 }
58
59 @Override
60 public synchronized long getWrites() {
61 return writes;
62 }
63
64 @Override
65 public synchronized long getWriteBytes() {
66 return writeBytes;
67 }
68
69 @Override
70 public synchronized long getCurrentQueueLength() {
71 return currentQueueLength;
72 }
73
74 @Override
75 public synchronized long getTransferTime() {
76 return transferTime;
77 }
78
79 @Override
80 public synchronized long getTimeStamp() {
81 return timeStamp;
82 }
83
84 @Override
85 public List<HWPartition> getPartitions() {
86 return this.partitionList;
87 }
88
89 @Override
90 public synchronized boolean updateAttributes() {
91 long now = System.currentTimeMillis();
92 for (perfstat_disk_t stat : diskStats.get()) {
93 String name = Native.toString(stat.name);
94 if (name.equals(this.getName())) {
95
96 long blks = stat.rblks + stat.wblks;
97 if (blks == 0L) {
98 this.reads = stat.xfers;
99 this.writes = 0L;
100 } else {
101 long approximateReads = Math.round(stat.xfers * stat.rblks / (double) blks);
102 long approximateWrites = stat.xfers - approximateReads;
103
104 if (approximateReads > this.reads) {
105 this.reads = approximateReads;
106 }
107 if (approximateWrites > this.writes) {
108 this.writes = approximateWrites;
109 }
110 }
111 this.readBytes = stat.rblks * stat.bsize;
112 this.writeBytes = stat.wblks * stat.bsize;
113 this.currentQueueLength = stat.qdepth;
114 this.transferTime = stat.time;
115 this.timeStamp = now;
116 return true;
117 }
118 }
119 return false;
120 }
121
122
123
124
125
126
127
128
129 public static List<HWDiskStore> getDisks(Supplier<perfstat_disk_t[]> diskStats) {
130 Map<String, Pair<Integer, Integer>> majMinMap = Ls.queryDeviceMajorMinor();
131 List<AixHWDiskStore> storeList = new ArrayList<>();
132 for (perfstat_disk_t disk : diskStats.get()) {
133 String storeName = Native.toString(disk.name);
134 Pair<String, String> ms = Lscfg.queryModelSerial(storeName);
135 String model = ms.getA() == null ? Native.toString(disk.description) : ms.getA();
136 String serial = ms.getB() == null ? Constants.UNKNOWN : ms.getB();
137 storeList.add(createStore(storeName, model, serial, disk.size << 20, diskStats, majMinMap));
138 }
139 return storeList.stream()
140 .sorted(Comparator.comparingInt(
141 s -> s.getPartitions().isEmpty() ? Integer.MAX_VALUE : s.getPartitions().get(0).getMajor()))
142 .collect(Collectors.toList());
143 }
144
145 private static AixHWDiskStore createStore(String diskName, String model, String serial, long size,
146 Supplier<perfstat_disk_t[]> diskStats, Map<String, Pair<Integer, Integer>> majMinMap) {
147 AixHWDiskStore store = new AixHWDiskStore(diskName, model.isEmpty() ? Constants.UNKNOWN : model, serial, size,
148 diskStats);
149 store.partitionList = Lspv.queryLogicalVolumes(diskName, majMinMap);
150 store.updateAttributes();
151 return store;
152 }
153 }