View Javadoc
1   /*
2    * Copyright 2021-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.hardware.platform.mac;
6   
7   import java.util.Collections;
8   import java.util.HashMap;
9   import java.util.HashSet;
10  import java.util.List;
11  import java.util.Map;
12  import java.util.Set;
13  import java.util.stream.Collectors;
14  
15  import oshi.hardware.LogicalVolumeGroup;
16  import oshi.hardware.common.AbstractLogicalVolumeGroup;
17  import oshi.util.ExecutingCommand;
18  
19  final class MacLogicalVolumeGroup extends AbstractLogicalVolumeGroup {
20  
21      private static final String DISKUTIL_CS_LIST = "diskutil cs list";
22      private static final String LOGICAL_VOLUME_GROUP = "Logical Volume Group";
23      private static final String PHYSICAL_VOLUME = "Physical Volume";
24      private static final String LOGICAL_VOLUME = "Logical Volume";
25  
26      MacLogicalVolumeGroup(String name, Map<String, Set<String>> lvMap, Set<String> pvSet) {
27          super(name, lvMap, pvSet);
28      }
29  
30      static List<LogicalVolumeGroup> getLogicalVolumeGroups() {
31          Map<String, Map<String, Set<String>>> logicalVolumesMap = new HashMap<>();
32          Map<String, Set<String>> physicalVolumesMap = new HashMap<>();
33  
34          String currentVolumeGroup = null;
35          boolean lookForVGName = false;
36          boolean lookForPVName = false;
37          int indexOf;
38          // Parse `diskutil cs list` to populate logical volume map
39          for (String line : ExecutingCommand.runNative(DISKUTIL_CS_LIST)) {
40              if (line.contains(LOGICAL_VOLUME_GROUP)) {
41                  // Disks that follow should be attached to this VG
42                  lookForVGName = true;
43              } else if (lookForVGName) {
44                  indexOf = line.indexOf("Name:");
45                  if (indexOf >= 0) {
46                      currentVolumeGroup = line.substring(indexOf + 5).trim();
47                      lookForVGName = false;
48                  }
49              } else if (line.contains(PHYSICAL_VOLUME)) {
50                  lookForPVName = true;
51              } else if (line.contains(LOGICAL_VOLUME)) {
52                  lookForPVName = false;
53              } else {
54                  indexOf = line.indexOf("Disk:");
55                  if (indexOf >= 0) {
56                      if (lookForPVName) {
57                          physicalVolumesMap.computeIfAbsent(currentVolumeGroup, k -> new HashSet<>())
58                                  .add(line.substring(indexOf + 5).trim());
59                      } else {
60                          logicalVolumesMap.computeIfAbsent(currentVolumeGroup, k -> new HashMap<>())
61                                  .put(line.substring(indexOf + 5).trim(), Collections.emptySet());
62                      }
63                  }
64              }
65          }
66          return logicalVolumesMap.entrySet().stream()
67                  .map(e -> new MacLogicalVolumeGroup(e.getKey(), e.getValue(), physicalVolumesMap.get(e.getKey())))
68                  .collect(Collectors.toList());
69      }
70  }