forked from lf-edge/eve
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathzfs.go
302 lines (270 loc) · 12.8 KB
/
zfs.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
// Copyright (c) 2021 Zededa, Inc.
// SPDX-License-Identifier: Apache-2.0
package types
import (
"fmt"
"strings"
"time"
zconfig "github.com/lf-edge/eve-api/go/config"
uuid "github.com/satori/go.uuid"
)
const (
// ZVolDevicePrefix controlled by mdev
ZVolDevicePrefix = "/dev/zvol"
// ZFSSnapshotter is containerd snapshotter for zfs
ZFSSnapshotter = "zfs"
// ZFSBinary is the zfs binary
ZFSBinary = "zfs"
// ZPoolBinary is the zpool binary
ZPoolBinary = "zpool"
)
// ZVolName returns name of zvol for volume
func (status VolumeStatus) ZVolName() string {
pool := VolumeClearZFSDataset
if status.Encrypted {
pool = VolumeEncryptedZFSDataset
}
return fmt.Sprintf("%s/%s.%d", pool, status.VolumeID.String(),
status.GenerationCounter+status.LocalGenerationCounter)
}
// ZVolName returns name of zvol for volume
func (status VolumeCreatePending) ZVolName() string {
pool := VolumeClearZFSDataset
if status.Encrypted {
pool = VolumeEncryptedZFSDataset
}
return fmt.Sprintf("%s/%s.%d", pool, status.VolumeID.String(),
status.GenerationCounter+status.LocalGenerationCounter)
}
// UseZVolDisk returns true if we should use zvol for the provided VolumeStatus and PersistType
func (status VolumeStatus) UseZVolDisk(persistType PersistType) bool {
if status.IsContainer() {
return false
}
if status.ContentFormat == zconfig.Format_ISO {
return false
}
return persistType == PersistZFS
}
// ZVolStatus specifies the needed information for zfs volume
type ZVolStatus struct {
Dataset string
Device string
}
// Key is Dataset with '/' replaced by '_'
func (status ZVolStatus) Key() string {
return strings.ReplaceAll(status.Dataset, "/", "_")
}
// PoolStatus type value from ZFS
type PoolStatus uint32
// PoolStatus value.
//
// The following correspond to faults as defined in enum zfs_error in the
// libzfs.h header file. But we add +1 to their values to that we can
// have a Unspecified=0 value to follow our conventions. Basically that the
// definitions should follow that in the (fault.fs.zfs.*) event namespace.
const (
PoolStatusUnspecified PoolStatus = iota // Unspecified
PoolStatusCorruptCache // PoolStatusCorruptCache - corrupt /kernel/drv/zpool.cache
PoolStatusMissingDevR // missing device with replicas
PoolStatusMissingDevNr // missing device with no replicas
PoolStatusCorruptLabelR // bad device label with replicas
PoolStatusCorruptLabelNr // bad device label with no replicas
PoolStatusBadGUIDSum // sum of device guids didn't match
PoolStatusCorruptPool // pool metadata is corrupted
PoolStatusCorruptData // data errors in user (meta)data
PoolStatusFailingDev // device experiencing errors
PoolStatusVersionNewer // newer on-disk version
PoolStatusHostidMismatch // last accessed by another system
PoolStatusHosidActive // currently active on another system
PoolStatusHostidRequired // multihost=on and hostid=0
PoolStatusIoFailureWait // failed I/O, failmode 'wait'
PoolStatusIoFailureContinue // failed I/O, failmode 'continue'
PoolStatusIOFailureMMP // ailed MMP, failmode not 'panic'
PoolStatusBadLog // cannot read log chain(s)
PoolStatusErrata // informational errata available
PoolStatusUnsupFeatRead // If the pool has unsupported features but cannot be opened at all, its status is ZPOOL_STATUS_UNSUP_FEAT_READ.
PoolStatusUnsupFeatWrite // If the pool has unsupported features but can still be opened in read-only mode, its status is ZPOOL_STATUS_UNSUP_FEAT_WRITE
PoolStatusFaultedDevR // faulted device with replicas
PoolStatusFaultedDevNr // faulted device with no replicas
PoolStatusVersionOlder // older legacy on-disk version
PoolStatusFeatDisabled // supported features are disabled
PoolStatusResilvering // device being resilvered
PoolStatusOfflineDev // device offline
PoolStatusRemovedDev // removed device
PoolStatusRebuilding // device being rebuilt
PoolStatusRebuildScrub // recommend scrubbing the pool
PoolStatusNonNativeAshift // (e.g. 512e dev with ashift of 9)
PoolStatusCompatibilityErr // bad 'compatibility' property
PoolStatusIncompatibleFeat // feature set outside compatibility
PoolStatusOk // the indicates a healthy pool.
)
// VDevAux - vdev aux states
type VDevAux uint64
// VDevAux - vdev aux states. When a vdev is in the CANT_OPEN state, the aux field
// of the vdev stats structure uses these constants to distinguish why.
//
// But we add +1 to their values to that we can have a Unspecified=0 value
// to follow our conventions. Basically that the
// definitions should follow that in the vdev_aux enum in sys/fs/zfs.h.
const (
VDevAuxUnspecified VDevAux = iota // Unspecified
VDevAuxStatusOk // no error (normal state)
VDevAuxOpenFailed // ldi_open_*() or vn_open() failed
VDevAuxCorruptData // bad label or disk contents
VDevAuxNoReplicas // insufficient number of replicas
VDevAuxBadGUIDSum // vdev guid sum doesn't match
VDevAuxTooSmall // vdev size is too small
VDevAuxBadLabel // the label is OK but invalid
VDevAuxVersionNewer // on-disk version is too new
VDevAuxVersionOlder // on-disk version is too old
VDevAuxUnsupFeat // unsupported features
VDevAuxSpared // hot spare used in another pool
VDevAuxErrExceeded // too many errors
VDevAuxIOFailure // experienced I/O failure
VDevAuxBadLog // cannot read log chain(s)
VDevAuxExternal // external diagnosis
VDevAuxSplitPool // vdev was split off into another pool
VdevAuxBadAshift // vdev ashift is invalid
VdevAuxExternalPersist // persistent forced fault
VdevAuxActive // vdev active on a different host
VdevAuxChildrenOffline // all children are offline
VdevAuxAshiftTooBig // vdev's min block size is too large
)
// StorageRaidType indicates storage raid type
type StorageRaidType int32
// StorageRaidType enum should be in sync with info api
const (
StorageRaidTypeUnspecified StorageRaidType = 0
StorageRaidTypeRAID0 StorageRaidType = 1 // RAID-0
StorageRaidTypeRAID1 StorageRaidType = 2 // Mirror
StorageRaidTypeRAID5 StorageRaidType = 3 // raidz1 (RAID-5)
StorageRaidTypeRAID6 StorageRaidType = 4 // raidz2 (RAID-6)
StorageRaidTypeRAID7 StorageRaidType = 5 // raidz3 (RAID-7)
StorageRaidTypeNoRAID StorageRaidType = 6 // without RAID
)
// StorageStatus indicates current status of storage
type StorageStatus int32
// StorageStatus enum should be in sync with info api
const (
StorageStatusUnspecified StorageStatus = 0
StorageStatusOnline StorageStatus = 1 // The device or virtual device is in normal working order.
StorageStatusDegraded StorageStatus = 2 // The virtual device has experienced a failure but can still function.
StorageStatusFaulted StorageStatus = 3 // The device or virtual device is completely inaccessible.
StorageStatusOffline StorageStatus = 4 // The device has been explicitly taken offline by the administrator.
StorageStatusUnavail StorageStatus = 5 // The device or virtual device cannot be opened. In some cases, pools with UNAVAIL devices appear in DEGRADED mode.
StorageStatusRemoved StorageStatus = 6 // The device was physically removed while the system was running.
StorageStatusSuspended StorageStatus = 7 // A pool that is waiting for device connectivity to be restored.
)
// ZFSPoolStatus stores collected information about zpool
type ZFSPoolStatus struct {
PoolName string
ZfsVersion string
CurrentRaid StorageRaidType
CompressionRatio float64
ZpoolSize uint64
CountZvols uint32
StorageState StorageStatus
Disks []*StorageDiskState
CollectorErrors string
Children []*StorageChildren
PoolStatusMsg PoolStatus // pool status value from ZFS
PoolStatusMsgStr string // pool status value from ZFS in string format
}
// Key for pubsub
func (s ZFSPoolStatus) Key() string {
return s.PoolName
}
// DiskDescription stores disk information
type DiskDescription struct {
Name string // bus-related name, for example: /dev/sdc
LogicalName string // logical name, for example: disk3
Serial string // serial number of disk
}
// ZIOType - IO types in ZFS.
// These values are used to access the data in the
// arrays (Ops/Bytes) with statistics coming from libzfs.
// ZIOTypeMax value determines the number of ZIOType in this enum.
// (Should always be the last in this enum)
const (
ZIOTypeNull = iota
ZIOTypeRead
ZIOTypeWrite
ZIOTypeFree
ZIOTypeClaim
ZIOTypeIoctl
ZIOTypeMax // ZIOTypeMax value determines the number of ZIOType in this enum. (Should always be the last in this enum)
)
// ZFSVDevMetrics metrics for VDev from ZFS and /proc/diskstats
type ZFSVDevMetrics struct {
Alloc uint64 // space allocated (in byte)
Space uint64 // total capacity (in byte)
DSpace uint64 // deflated capacity (in byte)
RSize uint64 // replaceable dev size (in byte)
ESize uint64 // expandable dev size (in byte)
ReadErrors uint64 // read errors
WriteErrors uint64 // write errors
ChecksumErrors uint64 // checksum errors
Ops [ZIOTypeMax]uint64 // operation count
Bytes [ZIOTypeMax]uint64 // bytes read/written
IOsInProgress uint64 // IOsInProgress is number of I/Os currently in progress.
ReadTicks uint64 // ReadTicks is the total number of milliseconds spent by all reads.
WriteTicks uint64 // WriteTicks is the total number of milliseconds spent by all writes.
IOsTotalTicks uint64 // IOsTotalTicks is the number of milliseconds spent doing I/Os.
// WeightedIOTicks is the weighted number of milliseconds spent doing I/Os.
// This can also be used to estimate average queue wait time for requests.
WeightedIOTicks uint64
}
// StorageDiskState represent state of disk
type StorageDiskState struct {
DiskName *DiskDescription
Status StorageStatus
AuxState VDevAux
AuxStateStr string // AuxState in string format
}
// StorageChildren stores children of zfs pool
type StorageChildren struct {
DisplayName string
CurrentRaid StorageRaidType
// GUID - a unique value for the binding.
// Since the DisplayName may not be unique. This may be important
// for accurate matching with other information.
// Actual case only for RAID or Mirror.
GUID uint64
Disks []*StorageDiskState
Children []*StorageChildren
}
// StorageZVolMetrics stores metrics for zvol (/dev/zd*)
type StorageZVolMetrics struct {
VolumeID uuid.UUID // From VolumeStatus.VolumeID. Ex: c546e61f-ffd9-406e-9074-8b19b417510d
Metrics *ZFSVDevMetrics // Metrics for zdev from /proc/diskstats
}
// StorageDiskMetrics represent metrics of disk
type StorageDiskMetrics struct {
DiskName *DiskDescription
Metrics *ZFSVDevMetrics // metrics for disk from ZFS and /proc/diskstats
}
// StorageChildrenMetrics stores metrics for children of zfs pool
type StorageChildrenMetrics struct {
DisplayName string
// GUID - a unique value for the binding.
// Since the DisplayName may not be unique.
GUID uint64
// Metrics from ZFS. Displays the sum of metrics from all disks it consists of.
Metrics *ZFSVDevMetrics
Disks []*StorageDiskMetrics
Children []*StorageChildrenMetrics
}
// ZFSPoolMetrics - stores metrics for the pool including all child devices
type ZFSPoolMetrics struct {
PoolName string
CollectionTime time.Time // Time when the metrics was collected
Metrics *ZFSVDevMetrics // Metrics and error counters for zfs pool
ChildrenDataset []*StorageChildrenMetrics // Children metrics for datasets (RAID or Mirror)
Disks []*StorageDiskMetrics // Metrics for disks that are not included in the RAID or mirror
ZVols []*StorageZVolMetrics // Metrics for zvols from /proc/diskstats
}
// Key for pubsub ZFSPoolMetrics
func (s ZFSPoolMetrics) Key() string {
return s.PoolName
}