Skip to content

Commit d88e6f2

Browse files
committed
Use WMI to implement Disk API to reduce PowerShell overhead
1 parent 24a83d6 commit d88e6f2

File tree

2 files changed

+366
-179
lines changed

2 files changed

+366
-179
lines changed

pkg/cim/disk.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ const (
2828
ErrorCodeCreatePartitionAccessPathAlreadyInUse = 42002
2929
)
3030

31+
var (
32+
DiskSelectorListForDiskNumberAndLocation = []string{"Number", "Location"}
33+
DiskSelectorListForPartitionStyle = []string{"PartitionStyle"}
34+
DiskSelectorListForPathAndSerialNumber = []string{"Path", "SerialNumber"}
35+
DiskSelectorListForIsOffline = []string{"IsOffline"}
36+
DiskSelectorListForSize = []string{"Size"}
37+
)
38+
3139
// QueryDiskByNumber retrieves disk information for a specific disk identified by its number.
3240
//
3341
// The equivalent WMI query is:
@@ -52,6 +60,43 @@ func QueryDiskByNumber(diskNumber uint32, selectorList []string) (*storage.MSFT_
5260
return disk, nil
5361
}
5462

63+
// ListDisks retrieves information about all available disks.
64+
//
65+
// The equivalent WMI query is:
66+
//
67+
// SELECT [selectors] FROM MSFT_Disk
68+
//
69+
// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-disk
70+
// for the WMI class definition.
71+
func ListDisks(selectorList []string) ([]*storage.MSFT_Disk, error) {
72+
diskQuery := query.NewWmiQueryWithSelectList("MSFT_Disk", selectorList)
73+
instances, err := QueryInstances(WMINamespaceStorage, diskQuery)
74+
if IgnoreNotFound(err) != nil {
75+
return nil, err
76+
}
77+
78+
var disks []*storage.MSFT_Disk
79+
for _, instance := range instances {
80+
disk, err := storage.NewMSFT_DiskEx1(instance)
81+
if err != nil {
82+
return nil, fmt.Errorf("failed to query disk %v. error: %v", instance, err)
83+
}
84+
85+
disks = append(disks, disk)
86+
}
87+
88+
return disks, nil
89+
}
90+
91+
// InitializeDisk initializes a RAW disk with a particular partition style.
92+
//
93+
// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/initialize-msft-disk
94+
// for the WMI method definition.
95+
func InitializeDisk(disk *storage.MSFT_Disk, partitionStyle int) (int, error) {
96+
result, err := disk.InvokeMethodWithReturn("Initialize", int32(partitionStyle))
97+
return int(result), err
98+
}
99+
55100
// RefreshDisk Refreshes the cached disk layout information.
56101
//
57102
// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-disk-refresh
@@ -61,3 +106,85 @@ func RefreshDisk(disk *storage.MSFT_Disk) (int, string, error) {
61106
result, err := disk.InvokeMethodWithReturn("Refresh", &status)
62107
return int(result), status, err
63108
}
109+
110+
// CreatePartition creates a partition on a disk.
111+
//
112+
// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/createpartition-msft-disk
113+
// for the WMI method definition.
114+
func CreatePartition(disk *storage.MSFT_Disk, params ...interface{}) (int, error) {
115+
result, err := disk.InvokeMethodWithReturn("CreatePartition", params...)
116+
return int(result), err
117+
}
118+
119+
// SetDiskState takes a disk online or offline.
120+
//
121+
// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-disk-online and
122+
// https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-disk-offline
123+
// for the WMI method definition.
124+
func SetDiskState(disk *storage.MSFT_Disk, online bool) (int, string, error) {
125+
method := "Offline"
126+
if online {
127+
method = "Online"
128+
}
129+
130+
var status string
131+
result, err := disk.InvokeMethodWithReturn(method, &status)
132+
return int(result), status, err
133+
}
134+
135+
// RescanDisks rescans all changes by updating the internal cache of software objects (that is, Disks, Partitions, Volumes)
136+
// for the storage setting.
137+
//
138+
// Refer to https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/msft-storagesetting-updatehoststoragecache
139+
// for the WMI method definition.
140+
func RescanDisks() (int, error) {
141+
result, _, err := InvokeCimMethod(WMINamespaceStorage, "MSFT_StorageSetting", "UpdateHostStorageCache", nil)
142+
return result, err
143+
}
144+
145+
// GetDiskNumber returns the number of a disk.
146+
func GetDiskNumber(disk *storage.MSFT_Disk) (uint32, error) {
147+
number, err := disk.GetProperty("Number")
148+
if err != nil {
149+
return 0, err
150+
}
151+
return uint32(number.(int32)), err
152+
}
153+
154+
// GetDiskLocation returns the location of a disk.
155+
func GetDiskLocation(disk *storage.MSFT_Disk) (string, error) {
156+
return disk.GetPropertyLocation()
157+
}
158+
159+
// GetDiskPartitionStyle returns the partition style of a disk.
160+
func GetDiskPartitionStyle(disk *storage.MSFT_Disk) (int32, error) {
161+
retValue, err := disk.GetProperty("PartitionStyle")
162+
if err != nil {
163+
return 0, err
164+
}
165+
return retValue.(int32), err
166+
}
167+
168+
// IsDiskOffline returns whether a disk is offline.
169+
func IsDiskOffline(disk *storage.MSFT_Disk) (bool, error) {
170+
return disk.GetPropertyIsOffline()
171+
}
172+
173+
// GetDiskSize returns the size of a disk.
174+
func GetDiskSize(disk *storage.MSFT_Disk) (int64, error) {
175+
sz, err := disk.GetProperty("Size")
176+
if err != nil {
177+
return -1, err
178+
}
179+
return strconv.ParseInt(sz.(string), 10, 64)
180+
}
181+
182+
// GetDiskPath returns the path of a disk.
183+
func GetDiskPath(disk *storage.MSFT_Disk) (string, error) {
184+
return disk.GetPropertyPath()
185+
}
186+
187+
// GetDiskSerialNumber returns the serial number of a disk.
188+
func GetDiskSerialNumber(disk *storage.MSFT_Disk) (string, error) {
189+
return disk.GetPropertySerialNumber()
190+
}

0 commit comments

Comments
 (0)