/
blockdevice.go
471 lines (378 loc) · 14 KB
/
blockdevice.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
/*
Copyright 2019 The OpenEBS Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package blockdevice
// BlockDevice is an internal representation of any block device present on the system.
// All data related to that device will be held by this struct
//
// 1. Example blockdevice struct for a partition /dev/sda1
// {
// Identifier:{
// UUID:blockdevice-4c25d69f9adc868f61e3d891cf3a5613
// SysPath:/sys/dev/block/8:1
// DevPath:/dev/sda1
// }
// NodeAttributes:map[hostname:my-machine]
// FSInfo:{
// FileSystemUUID:7e7f160b-0e79-478b-b006-1ebc6d0050dd
// FileSystem:ext4
// MountPoint:[/home]
// }
// Parent:/dev/sda
// Partitions:[]
// Holders:[]
// Slaves:[]
// Status:{
// State:Active
// ClaimPhase:Unclaimed
// }
// }
//
// 2. Example blockdevice struct for a partition that is part of an LVM
// {
// Identifier:{
// UUID:blockdevice-4c25d69f9adc868f61e3d891cf3a5613
// SysPath:/sys/dev/block/8:1
// DevPath:/dev/sda1
// }
// NodeAttributes:map[hostname:my-machine]
// FSInfo:{
// FileSystemUUID:AQkPql-2MBI-O5cY-gn3O-EFvZ-66Oe-d4mnjD
// FileSystem:LVM2_member
// MountPoint:[]
// }
// Parent:/dev/sda
// Partitions:[]
// Holders:[/dev/dm-0]
// Slaves:[]
// Status:{
// State:Active
// ClaimPhase:Unclaimed
// }
// }
// 3. Example blockdevice struct for an LVM carved from nvme partition
// {
// Identifier:{
// UUID:blockdevice-4c25d69f9adc868f61e3d891cf3a5613
// SysPath:/sys/dev/block/253:0
// DevPath:/dev/dm-0
// }
// NodeAttributes:map[hostname:my-machine]
// FSInfo:{
// FileSystemUUID:7e7f160b-0e79-478b-b006-1ebc6d0050dd
// FileSystem:ext4
// MountPoint:[]
// }
// Parent:
// Partitions:[]
// Holders:[]
// Slaves:[/dev/nvme0n1p1 /dev/nvme0n1p2]
// Status:{
// State:Active
// ClaimPhase:Unclaimed
// }
// }
//
type BlockDevice struct {
// Identifier is the unique identifiers that can be used to identify this
// blockdevice
Identifier
// NodeAttributes contains the details of the node on which
// the BlockDevice is attached
NodeAttributes NodeAttribute
// Labels for this blockdevice. These labels will be used on the k8s resource that is created
// optional
Labels map[string]string
// FSInfo contains the file system related information of this
// BlockDevice if it exists
FSInfo FileSystemInformation
// Capacity contains the capacity related information for this blockdevice
Capacity CapacityInformation
// DevLinks contain the devlinks of this blockdevice
DevLinks []DevLink
// DeviceAttributes contains the attributes of this device, like hardcoded
// information on the disk
DeviceAttributes DeviceAttribute
// DMInfo is filled if the device is a DM device
DMInfo DeviceMapperInformation
DevUse DeviceUsage
// PartitionInfo contains details if this blockdevice is a partition
PartitionInfo PartitionInformation
// DependentDevices stores the dependent devices
DependentDevices DependentBlockDevices
SMARTInfo SMARTStats
// Status contains the state of the blockdevice
Status Status
}
// SMARTStats represents stats from SMART spec and data fetched/calculated by data from seachest
type SMARTStats struct {
// RotationRate stores the rotation rate of a block device, only applicable for HDD
RotationRate uint16
// RotationalLatency stores the latency of the drive, only applicable for HDD
RotationalLatency float64
// TemperatureInfo stores the temperature information of the drive
TemperatureInfo TemperatureInformation
// TotalBytesRead stores the total amount of bytes read by a block device
TotalBytesRead uint64
// TotalBytesWritten stores the total amount of bytes written by a block device
TotalBytesWritten uint64
// UtilizationRate stores the rate of utilization of a block device
UtilizationRate float64
// PercentEnduranceUsed stores the endurance used in percent
PercentEnduranceUsed float64
}
// Identifier represents the various identifiers that can be used to
// identify this blockdevice uniquely on the host
type Identifier struct {
// UUID is a system generated unique ID for this blockdevice
UUID string
// SysPath is the syspath of this device.
// Eg : /sys/dev/block/8:1
SysPath string
// DevPath is the name of the device in /dev
DevPath string
}
// NodeAttribute is the representing the various attributes of the machine
// on which this block device is present
type NodeAttribute map[string]string
const (
// HostName is the hostname of the system on which this BD is present
HostName string = "hostname"
// NodeName is the nodename (may be FQDN) on which this BD is present
NodeName string = "nodename"
// ZoneName is the zone in which the system is present.
//
// NOTE: Valid only for cloud providers
ZoneName string = "zone"
// RegionName is the region in which the system is present.
//
// NOTE: Valid only for cloud providers
RegionName string = "region"
)
const (
// SparseBlockDeviceType is the sparse blockdevice type
SparseBlockDeviceType = "sparse"
// BlockDeviceType is the type for blockdevice.
BlockDeviceType = "blockdevice"
// BlockDevicePrefix is the prefix used in UUIDs
BlockDevicePrefix = BlockDeviceType + "-"
// The following blockdevice types correspond to the types as seen by the host system
// BlockDeviceTypeDisk represents a disk type
BlockDeviceTypeDisk = "disk"
// BlockDeviceTypePartition represents a partition
BlockDeviceTypePartition = "partition"
// BlockDeviceTypeLoop represents a loop device
BlockDeviceTypeLoop = "loop"
// BlockDeviceTypeDMDevice is a dm device
BlockDeviceTypeDMDevice = "dm"
// BlockDeviceTypeLVM is an lvm device type
BlockDeviceTypeLVM = "lvm"
// BlockDeviceTypeCrypt is a LUKS volume
BlockDeviceTypeCrypt = "crypt"
// BlockDeviceTypeMultiPath is a multipath device
BlockDeviceTypeMultiPath = "mpath"
)
// DeviceMapperDeviceTypes is the slice of device types that uses a device mapper
var DeviceMapperDeviceTypes = []string{
BlockDeviceTypeDMDevice,
BlockDeviceTypeLVM,
BlockDeviceTypeCrypt,
BlockDeviceTypeMultiPath,
}
const (
// DriveTypeHDD represents a rotating hard disk drive
DriveTypeHDD = "HDD"
// DriveTypeSSD represents a solid state drive
DriveTypeSSD = "SSD"
// DriveTypeUnknown is used when the drive type of the disk could not be determined.
DriveTypeUnknown = "Unknown"
)
// FileSystemInformation contains the filesystem and mount information of blockdevice, if present
type FileSystemInformation struct {
// FileSystemUUID is the UUID of the filesystem on the blockdevice
FileSystemUUID string
// FileSystem is the filesystem present on the blockdevice
FileSystem string
// MountPoint is the list of mountpoints at which this blockdevice is mounted
MountPoint []string
}
// CapacityInformation holds the capacity related information for the device
type CapacityInformation struct {
// Storage is the storage capacity of this blockdevice
// in bytes
Storage uint64
}
// DeviceAttribute represents the hardcoded information on the device.
// It is not gauranteed that all these fields should be present for a given
// blockdevice
type DeviceAttribute struct {
// DeviceType is the type of the blockdevice.
// Values can be sparse/disk/partition/loop/lvm/raid etc
DeviceType string
// DriveType is the type of backing drive for this blockdevice. HDD/SSD
DriveType string
// IDType is the udev ID_TYPE field. This is solely used for purpose of UUID generation
// using the old algorithm
IDType string
// PhysicalBlockSize is the physical block size in bytes
// reported by /sys/class/block/sda/queue/physical_block_size
//
// This is the unit in which the disk actually reads and writes
// the data atomically. Certain 4K sector devices may use a
// 4K 'physical_block_size' internally but expose a finer-grained
// 512 byte 'logical_block_size' to Linux. Also the current HDDs
// are advanced format (https://en.wikipedia.org/wiki/Advanced_Format)
// so they support 4k physical sector size.
PhysicalBlockSize uint32
// LogicalBlockSize is the logical block size in bytes
// reported by /sys/class/block/sda/queue/logical_block_size
//
// The smallest size the drive is able to write. This can be
// different than hw_sector_size as disks may lie about this
// to support lower/higher sector size. This is important for
// direct IOs, as IOs should be aligned on a 'logical_block_size'
// boundaries.
LogicalBlockSize uint32
// HardwareSectorSize is the hardware sector size in bytes
// reported by /sys/class/block/sda/queue/hw_sector_size
//
// This is the actual sector size of the disk
HardwareSectorSize uint32
// WWN
WWN string
// Vendor
Vendor string
// Model of the device
// Eg : PersistentDisk, Virtaul_disk, QEMU_HARDDISK, EphemeralDisk
Model string
// Serial number of the device
Serial string
// FirmwareRevision
FirmwareRevision string
// Compliance is implemented specifications version i.e. SPC-1, SPC-2, etc
Compliance string
}
// DevLink represents a type of dev link for a device. A device can have multiple
// kinds of devlink and each kind can have more than one link
type DevLink struct {
// Kind is the type of devlink.
// Eg: by-id, by-path, by-uuid, by-partuuid
Kind string
// Links is the list of actual links that point to the device
Links []string
}
// TemperatureInformation stores the temperature information of the blockdevice
type TemperatureInformation struct {
// CurrentTemperatureDataValid specifies whether the current temperature
// data reported is valid or not
CurrentTemperatureDataValid bool
// LowestTemperatureDataValid specifies whether the lowest temperature
// data reported is valid or not
LowestTemperatureDataValid bool
// HighestTemperatureDataValid specifies whether the highest temperature
// data reported is valid or not
HighestTemperatureDataValid bool
// CurrentTemperature is the temperature of the drive in celsius
CurrentTemperature int16
// LowestTemperature is the lowest temperature of the drive recorded in celsius
LowestTemperature int16
// HighestTemperature is the highest temperature of the drive recorded in celsius
HighestTemperature int16
}
// PartitionInformation contains information related to the partition, if this
// blockdevice is a partition
type PartitionInformation struct {
// PartitionNumber is the partition number
PartitionNumber uint8
// PartitionEntryUUID is the UUID of the partition
PartitionEntryUUID string
// PartitionTableUUID is the UUID of the partition table
PartitionTableUUID string
// PartitionTableType is the type of the partition (dos/gpt)
PartitionTableType string
}
type DeviceMapperInformation struct {
// DMUUID is the UUID of the device as present in <dev-sys-path>/dm/uuid
DMUUID string
// DevMapperPath is the device mapper path. It will be of the format /dev/mapper/<mapper>
// This path will be a symlink to the actual dm-X device node
DevMapperPath string
}
// DependentBlockDevices contains path of all devices that are
// related to this BlockDevice
type DependentBlockDevices struct {
// Parent is the parent device of this blockdevice, if it exists.
// It will always be a single device.
Parent string
// Partitions is the list of partitions(again blockdevices) for
// this blockdevice, if it exists.
Partitions []string
// Holders is the list of blockdevices that are held by this blockdevice.
// eg: sda1 can hold dm-0. Then the list of sda1 will contain dm-0.
Holders []string
// Slaves is the list of blockdevices to which this blockdevice is a slave.
// Slaves are represented in SysFS under the block device layer,
// so they are dependent on the device
// eg: dm-0 is a slave to sda1. Then the list of dm-0 will contain sda1
Slaves []string
}
// DeviceUsage defines if the block device is used by any known storage engines
type DeviceUsage struct {
InUse bool
UsedBy StorageEngine
}
// StorageEngine is a typed string for the storage engine
type StorageEngine string
const (
// CStor
CStor StorageEngine = "cstor"
// ZFSLocalPV
ZFSLocalPV StorageEngine = "zfs-localpv"
// Mayastor
Mayastor StorageEngine = "mayastor"
// LocalPV
LocalPV StorageEngine = "localpv"
// Jiva
Jiva StorageEngine = "jiva"
)
// Status is used to represent the status of the blockdevice
type Status struct {
// State is the state of this BD like Active(Online), Inactive(Offline) or
// Unknown
State string
// ClaimPhase is the phase of this BD when is it is being used by NDM consumers
ClaimPhase string
}
const (
// Active means blockdevice is available on the host machine
Active string = "Active"
// Inactive means blockdevice is currently not available on the host machine
Inactive string = "Inactive"
// Unknown means the state cannot be determined at this point of time
Unknown string = "Unknown"
// Claimed means the blockdevice is in use
Claimed string = "Claimed"
// Released means the blockdevice is not in use, but cannot be claimed,
// because of some pending cleanup tasks
Released string = "Released"
// Unclaimed means the blockdevice is free and is available for
// claiming
Unclaimed string = "Unclaimed"
)
// Hierarchy is the block device hierarchy on the system.
// This map will be used as in memory cache for storing the current state of
// all block devices on the system. This cache helps to get the details of any
// dependent blockdevices from a device.
// eg: If at a certain point, we are processing sda1 and we need to get the UUID
// of its parent device. We will get /dev/sda is the parent of /dev/sda1.
// This will be used to query the cache and get/generate the UUID of /dev/sda.
type Hierarchy map[string]BlockDevice