forked from hpe-storage/common-host-libs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
filesystem.go
144 lines (128 loc) · 5.33 KB
/
filesystem.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
package tunelinux
// Copyright 2019 Hewlett Packard Enterprise Development LP.
import (
"github.com/hpe-storage/common-host-libs/linux"
log "github.com/hpe-storage/common-host-libs/logger"
"github.com/hpe-storage/common-host-libs/model"
)
var (
fsOptionMap = map[string]bool{
"discard": false,
"nobarrier": false,
"_netdev": false}
fsOptionDescriptionMap = map[string]string{
"discard": "Enable discard option to allow auto space reclamation using UNMAP",
"nobarrier": "Enable nobarrier to disable write barriers on SSD drives",
"_netdev": "Enable _netdev for iSCSI mount devices to allow network to be up before mounting device"}
)
// getDiscardRecommendation : get template for recommendation related to discard option for filesystem
func getRecommendationByFsOption(mountPoint *model.Mount, option string, currentStatus string, recommended bool) (recommendation *Recommendation) {
var optionSetting *Recommendation
var recommendedStatus = "enabled" // set enabled status by default
var complianceStatus string
var description = fsOptionDescriptionMap[option]
// ignore _netdev option for FC devices
if option == "_netdev" && mountPoint.Device.IscsiTarget == nil {
return nil
}
// ignore discard option for ext3 based filesystems as its not supported
if option == "discard" {
fsType, err := linux.GetFsType(*mountPoint)
if err != nil {
// device might got unmounted, ignore the recommenation
return nil
} else if fsType == linux.FsType.String(linux.Ext3) {
return nil
}
}
if recommended && currentStatus == "enabled" {
complianceStatus = ComplianceStatus.String(Recommended)
} else if recommended && currentStatus == "disabled" {
// missing option case
complianceStatus = ComplianceStatus.String(NotRecommended)
} else {
// invalid option present but not recommended
recommendedStatus = "disabled"
complianceStatus = ComplianceStatus.String(NotRecommended)
}
optionSetting = &Recommendation{
ID: linux.HashMountID(option + mountPoint.Device.AltFullPathName + mountPoint.Device.SerialNumber),
Category: Category.String(Filesystem),
Level: Severity.String(Warning),
Description: description,
Parameter: option,
Value: currentStatus,
Recommendation: recommendedStatus,
CompliantStatus: complianceStatus,
Device: mountPoint.Device.AltFullPathName,
FsType: "", // TODO identify filesystem type
Vendor: "",
}
log.Trace("Option settings for ", option)
log.Trace(optionSetting.Category, optionSetting.Parameter, optionSetting.Value, optionSetting.Recommendation, optionSetting.Description)
return optionSetting
}
// getRecommendationForMountDevice : obtain recommendations based on mount options for the device
func getRecommendationForMountDevice(mountPoint *model.Mount) (settings []*Recommendation, err error) {
log.Trace("getRecommendationForMountDevice called with ", mountPoint.Device.AltFullPathName)
var options []string
var recommendations []*Recommendation
var recommendation *Recommendation
// get options used to mount the device
options, err = linux.GetMountOptionsForDevice(mountPoint.Device)
if err != nil {
log.Error("Unable to get mount options for device ", mountPoint.Device.AltFullPathName, err.Error())
return nil, err
}
//now we got mount options for the device. verify and create recommendations
for index := range options {
_, present := fsOptionMap[options[index]]
if present == true {
// option is recommended and enabled, set value as true to indicate this option is set.
fsOptionMap[options[index]] = true
recommendation = getRecommendationByFsOption(mountPoint, options[index], "enabled", true)
if recommendation != nil {
// append recommendation for each option
recommendations = append(recommendations, recommendation)
}
}
}
// now get the recommendations for missing options, i.e options with value as false (not set)
for option, value := range fsOptionMap {
if value == false {
// missing option case, indicate this is needed
recommendation = getRecommendationByFsOption(mountPoint, option, "disabled", true)
if recommendation != nil {
// append recommendation for each option
recommendations = append(recommendations, recommendation)
}
}
}
log.Trace("total recommendations for mount device ", len(recommendations))
return recommendations, nil
}
// GetFileSystemRecommendations obtain various recommendations for filesystems mounted on host
func GetFileSystemRecommendations(devices []*model.Device) (settings []*Recommendation, err error) {
log.Trace(">>>>> GetFilesystemRecommendations")
defer log.Trace("<<<<< GetFileSystemRecommendations")
//var recommendations []*Recommendation
var deviceRecommendations []*Recommendation
var recommendations []*Recommendation
// Get all mounts from nimble devices
mounts, err := linux.GetMountPointsForDevices(devices)
if err != nil {
log.Error("Unable to get mount points for devices " + err.Error())
return nil, err
}
for _, mountPoint := range mounts {
// get device specific recommendations
deviceRecommendations, err = getRecommendationForMountDevice(mountPoint)
// append to overall recommendations
if deviceRecommendations != nil {
for _, recommendation := range deviceRecommendations {
recommendations = append(recommendations, recommendation)
}
}
}
return recommendations, err
}