View Javadoc
1   /*
2    * Copyright 2020-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.driver.unix.solaris.disk;
6   
7   import java.util.ArrayList;
8   import java.util.List;
9   
10  import oshi.annotation.concurrent.ThreadSafe;
11  import oshi.hardware.HWPartition;
12  import oshi.util.Constants;
13  import oshi.util.ExecutingCommand;
14  import oshi.util.ParseUtil;
15  
16  /**
17   * Utility to query iostat
18   */
19  @ThreadSafe
20  public final class Prtvtoc {
21  
22      private static final String PRTVTOC_DEV_DSK = "prtvtoc /dev/dsk/";
23  
24      private Prtvtoc() {
25      }
26  
27      public static List<HWPartition> queryPartitions(String mount, int major) {
28          List<HWPartition> partList = new ArrayList<>();
29          // This requires sudo permissions; will result in "permission denied"
30          // otherwise in which case we return empty partition list
31          List<String> prtvotc = ExecutingCommand.runNative(PRTVTOC_DEV_DSK + mount);
32          // Sample output - see man prtvtoc
33          if (prtvotc.size() > 1) {
34              int bytesPerSector = 0;
35              String[] split;
36              // We have a result, parse partition table
37              for (String line : prtvotc) {
38                  // If line starts with asterisk we ignore except for the one
39                  // specifying bytes per sector
40                  if (line.startsWith("*")) {
41                      if (line.endsWith("bytes/sector")) {
42                          split = ParseUtil.whitespaces.split(line);
43                          if (split.length > 0) {
44                              bytesPerSector = ParseUtil.parseIntOrDefault(split[1], 0);
45                          }
46                      }
47                  } else if (bytesPerSector > 0) {
48                      // If bytes/sector is still 0, these are not real partitions so
49                      // ignore.
50                      // Lines without asterisk have 6 or 7 whitespaces-split values
51                      // representing (last field optional):
52                      // Partition Tag Flags Sector Count Sector Mount
53                      split = ParseUtil.whitespaces.split(line.trim());
54                      // Partition 2 is always the whole disk so we ignore it
55                      if (split.length >= 6 && !"2".equals(split[0])) {
56                          // First field is partition number
57                          String identification = mount + "s" + split[0];
58                          // major already defined as method param
59                          int minor = ParseUtil.parseIntOrDefault(split[0], 0);
60                          // Second field is tag. Parse:
61                          String name;
62                          switch (ParseUtil.parseIntOrDefault(split[1], 0)) {
63                          case 0x01:
64                          case 0x18:
65                              name = "boot";
66                              break;
67                          case 0x02:
68                              name = "root";
69                              break;
70                          case 0x03:
71                              name = "swap";
72                              break;
73                          case 0x04:
74                              name = "usr";
75                              break;
76                          case 0x05:
77                              name = "backup";
78                              break;
79                          case 0x06:
80                              name = "stand";
81                              break;
82                          case 0x07:
83                              name = "var";
84                              break;
85                          case 0x08:
86                              name = "home";
87                              break;
88                          case 0x09:
89                              name = "altsctr";
90                              break;
91                          case 0x0a:
92                              name = "cache";
93                              break;
94                          case 0x0b:
95                              name = "reserved";
96                              break;
97                          case 0x0c:
98                              name = "system";
99                              break;
100                         case 0x0e:
101                             name = "public region";
102                             break;
103                         case 0x0f:
104                             name = "private region";
105                             break;
106                         default:
107                             name = Constants.UNKNOWN;
108                             break;
109                         }
110                         // Third field is flags.
111                         String type;
112                         // First character writable, second is mountable
113                         switch (split[2]) {
114                         case "00":
115                             type = "wm";
116                             break;
117                         case "10":
118                             type = "rm";
119                             break;
120                         case "01":
121                             type = "wu";
122                             break;
123                         default:
124                             type = "ru";
125                             break;
126                         }
127                         // Fifth field is sector count
128                         long partSize = bytesPerSector * ParseUtil.parseLongOrDefault(split[4], 0L);
129                         // Seventh field (if present) is mount point
130                         String mountPoint = "";
131                         if (split.length > 6) {
132                             mountPoint = split[6];
133                         }
134                         partList.add(
135                                 new HWPartition(identification, name, type, "", partSize, major, minor, mountPoint));
136                     }
137                 }
138             }
139         }
140         return partList;
141     }
142 }