From cc7b5fc8b14c2a22e92ad43c74617535d570ab78 Mon Sep 17 00:00:00 2001 From: Adarsh Pratik <74596004+adarshpratikhpe@users.noreply.github.com> Date: Tue, 29 Mar 2022 13:03:35 +0530 Subject: [PATCH] CON-2295: Merge of multipath.conf is not comprehensive (#169) Signed-off-by: Adarsh Pratik --- linux/os.go | 41 +- mpathconfig/configresource.go | 43 +- mpathconfig/configresource_test.go | 2 +- tunelinux/config.go | 205 +++-- tunelinux/config/cloud_vm_config.json | 945 +++++++++++++++++------ tunelinux/config/config.json | 643 +++++++++------ tunelinux/config/multipath.conf.generic | 13 - tunelinux/config/multipath.conf.upstream | 13 - tunelinux/disk.go | 57 +- tunelinux/fc.go | 52 +- tunelinux/iscsi.go | 52 +- tunelinux/multipath.go | 202 ++--- 12 files changed, 1538 insertions(+), 730 deletions(-) diff --git a/linux/os.go b/linux/os.go index 926dcdb..b7fe305 100644 --- a/linux/os.go +++ b/linux/os.go @@ -19,13 +19,14 @@ package linux import ( "errors" "fmt" - log "github.com/hpe-storage/common-host-libs/logger" - "github.com/hpe-storage/common-host-libs/util" "os" "regexp" "strconv" "strings" "sync" + + log "github.com/hpe-storage/common-host-libs/logger" + "github.com/hpe-storage/common-host-libs/util" ) const ( @@ -96,6 +97,42 @@ func GetOsInfo() (*OsInfo, error) { return osInfo, nil } +func GetDistro() (string, error) { + osInfoLock.Lock() + defer osInfoLock.Unlock() + var out, distro string + if f, err := os.Stat(osReleaseFile); err == nil && !f.IsDir() && f.Size() != 0 { + // get only PRETTY_NAME field of os-release + var lines []string + lines, err = util.FileGetStrings(osReleaseFile) + for _, line := range lines { + if strings.Contains(line, "PRETTY_NAME") { + // remove quotes and key + out = strings.Replace(strings.Replace(line, "\"", "", -1), "PRETTY_NAME=", "", -1) + break + } + } + + if out != "" { + if strings.Contains(out, "Ubuntu") { + distro = "Ubuntu" + } else if strings.Contains(out, "Red Hat") { + distro = "Red Hat" + } else if strings.Contains(out, "Centos") { + distro = "Centos" + } else if strings.Contains(out, "SUSE") { + distro = "SUSE" + } else { + log.Info("Cannot determine Distro") + return "", errors.New("Undefined DistroType") + } + return distro, nil + } + } + return "", errors.New("Unable to determine DistroType") + +} + // GetKernelVersion returns OS kernel version func (o *OsInfo) GetKernelVersion() string { return strings.TrimSpace(o.kernelVersion) diff --git a/mpathconfig/configresource.go b/mpathconfig/configresource.go index 00976f0..7163c16 100644 --- a/mpathconfig/configresource.go +++ b/mpathconfig/configresource.go @@ -6,8 +6,6 @@ import ( "container/list" "errors" "fmt" - log "github.com/hpe-storage/common-host-libs/logger" - "github.com/hpe-storage/common-host-libs/util" "os" "path" "regexp" @@ -15,6 +13,9 @@ import ( "strings" "sync" "time" + + log "github.com/hpe-storage/common-host-libs/logger" + "github.com/hpe-storage/common-host-libs/util" ) const ( @@ -239,25 +240,21 @@ func addOption(section *Section, option string) { //checks for the section func isSection(line string) (bool, error) { - line = strings.TrimSpace(line) - prefixes := []string{"defaults", "blacklist", "blacklist_exceptions", "devices", "device", "multipaths", "multipath"} - for _, prefix := range prefixes { - r, err := regexp.Compile("^"+prefix+"\\s*[{]*$") - if err != nil { - return false, err - } - - if(r.MatchString(line)) { - return true, nil - } - } - - return false, nil -} - - + line = strings.TrimSpace(line) + prefixes := []string{"defaults", "blacklist", "blacklist_exceptions", "devices", "device", "multipaths", "multipath"} + for _, prefix := range prefixes { + r, err := regexp.Compile("^" + prefix + "\\s*[{]*$") + if err != nil { + return false, err + } + if r.MatchString(line) { + return true, nil + } + } + return false, nil +} // ParseConfig reads and parses give config file into sections func ParseConfig(filePath string) (config *Configuration, err error) { @@ -349,9 +346,9 @@ func SaveConfig(config *Configuration, filePath string) (err error) { return err } -// GetNimbleSection gets nimble device section in /etc/multipath.conf -func (config *Configuration) GetNimbleSection() (section *Section, err error) { - log.Trace("GetNimbleSection called") +// GetDeviceSection gets device section in /etc/multipath.conf +func (config *Configuration) GetDeviceSection(deviceType string) (section *Section, err error) { + log.Trace("GetDeviceSection called for device: ", deviceType) config.mutex.RLock() defer config.mutex.RUnlock() @@ -363,7 +360,7 @@ func (config *Configuration) GetNimbleSection() (section *Section, err error) { if s.GetChildren().Len() != 0 { for e := s.GetChildren().Front(); e != nil; e = e.Next() { childSection := e.Value.(*Section) - if childSection.GetName() == "device" && strings.Contains(childSection.properties["vendor"], "Nimble") { + if childSection.GetName() == "device" && strings.Contains(childSection.properties["vendor"], deviceType) { return childSection, nil } } diff --git a/mpathconfig/configresource_test.go b/mpathconfig/configresource_test.go index 0ed4097..8ba60f0 100644 --- a/mpathconfig/configresource_test.go +++ b/mpathconfig/configresource_test.go @@ -14,7 +14,7 @@ func TestParseDeviceSection(t *testing.T) { ) } else { // config found - section, err := config.GetNimbleSection() + section, err := config.GetDeviceSection() if err != nil { t.Error( "Parsing nimble device section failed ", err, diff --git a/tunelinux/config.go b/tunelinux/config.go index 8204bc1..6333289 100644 --- a/tunelinux/config.go +++ b/tunelinux/config.go @@ -4,12 +4,13 @@ package tunelinux import ( "encoding/json" "errors" - "github.com/hpe-storage/common-host-libs/linux" - log "github.com/hpe-storage/common-host-libs/logger" - "github.com/hpe-storage/common-host-libs/util" "io/ioutil" "os" "sync" + + "github.com/hpe-storage/common-host-libs/linux" + log "github.com/hpe-storage/common-host-libs/logger" + "github.com/hpe-storage/common-host-libs/util" ) // Category recommendation category type @@ -136,13 +137,29 @@ type TemplateSetting struct { Driver string `json:"driver,omitempty"` } +type DeviceTemplate struct { + DeviceType string + TemplateArray []TemplateSetting +} + +type DeviceRecommendation struct { + DeviceType string + RecomendArray []*Recommendation +} + +type DeviceMap struct { + DeviceType string + deviceMap map[string]string +} + var ( // Global config of template settings - templateSettings []TemplateSetting + deviceTemplate []DeviceTemplate // RW lock to prevent concurrent loading configLock = new(sync.RWMutex) // ConfigFile file path of template settings for recommendation. - ConfigFile = GetConfigFile() + ConfigFile = GetConfigFile() + defaultDeviceType = "Nimble" ) const ( @@ -179,55 +196,134 @@ func SetConfigFile(configFile string) { // loadTemplateSettings synchronize and load configuration for template of recommended settings // File read will only happen during initial load, so we take lock for complete loading. -// TODO: make this optional only when configfile option is provided. Use in-memory settings func loadTemplateSettings() (err error) { configLock.Lock() defer configLock.Unlock() - if len(templateSettings) != 0 { + + DeviceType := [2]string{"Nimble", "3PARdata"} + for _, deviceType := range DeviceType { + var configExist bool = false + + /* check if the initial device config is already read */ + /* TODO Find a more efficient way to check deviceType config exists */ + for _, devType := range deviceTemplate { + if devType.DeviceType == deviceType { + log.Tracef("%s device config exists. Skipping", deviceType) + configExist = true + } + } + // already loaded template settings from config file - // once the initial config is loaded, we should return most of the time from here - return nil - } - log.Traceln("Reading template config file:", ConfigFile) - file, err := ioutil.ReadFile(ConfigFile) - if err != nil { - log.Error("Template Config File read error: ", err.Error()) - return err - } - err = json.Unmarshal(file, &templateSettings) - if err != nil { - log.Error("Template Config File Unmarshall error: ", err.Error()) - return err + // once the initial config for deviceType is loaded, we should not repopulate it + if !configExist { + var devicetemplateSettings DeviceTemplate + log.Tracef("Reading template config file: %s , for device: %s", ConfigFile, deviceType) + + file, err := ioutil.ReadFile(ConfigFile) + if err != nil { + log.Error("Template Config File read error: ", err.Error()) + return err + } + + // Fetch device section from config.json + var result map[string]interface{} + err = json.Unmarshal(file, &result) + + if err != nil { + log.Error("Template Config File Unmarshal error: ", err.Error()) + return err + } + deviceSection := result[deviceType] + if deviceSection != nil { + distroType, err := linux.GetDistro() + if err != nil { + log.Trace("Received error while fetching distroType , using default configuration ", err.Error()) + distroType = "Default" + } + + log.Trace("Os DistroType ", distroType) + config := (deviceSection.(map[string]interface{}))[distroType] + if config == nil { + log.Warningf("Distro section: %s , not present for deviceType: %s , using default config", distroType, deviceType) + config = deviceSection.(map[string]interface{})["Default"] /* Default section is alays expected to present, hence no error check */ + } + // TODO Add version specific parsing for the distroType + switch config.(type) { + case interface{}: + for _, v := range config.([]interface{}) { + var temp TemplateSetting + convertmap := v.(map[string]interface{}) + temp.Category = convertmap["category"].(string) + temp.Parameter = convertmap["parameter"].(string) + temp.Recommendation = convertmap["recommendation"].(string) + temp.Level = convertmap["severity"].(string) + temp.Description = convertmap["description"].(string) + + if _, ok := convertmap["driver"]; ok { + temp.Driver = convertmap["driver"].(string) + } + + devicetemplateSettings.TemplateArray = append(devicetemplateSettings.TemplateArray, temp) + } + + default: + log.Tracef("%v is unknown \n ", config) + return errors.New("error: while Parsing section for deviceType : " + deviceType) + } + + } else { + log.Tracef("DeviceType: %s absent in config.json", deviceType) + return errors.New("error: unable to get deviceType " + deviceType) + } + + devicetemplateSettings.DeviceType = deviceType + deviceTemplate = append(deviceTemplate, devicetemplateSettings) + } } return nil } // get map of either parameter -> recommended value or param -> description fields for given category -func getParamToTemplateFieldMap(category Category, field string, driver string) (paramTemplateFieldMap map[string]string, err error) { - paramTemplateFieldMap = make(map[string]string) - for index := range templateSettings { - if templateSettings[index].Category == Category.String(category) { - if driver != "" && templateSettings[index].Driver != driver { - // obtain only specific driver params in a given category - continue - } - switch field { - case "recommendation": - // populate parameter -> recommended value map - paramTemplateFieldMap[templateSettings[index].Parameter] = templateSettings[index].Recommendation - case "description": - // populate parameter -> description map - paramTemplateFieldMap[templateSettings[index].Parameter] = templateSettings[index].Description - case "severity": - // populate parameter -> severity map - paramTemplateFieldMap[templateSettings[index].Parameter] = templateSettings[index].Level - default: - // populate parameter -> recommended value map by default - paramTemplateFieldMap[templateSettings[index].Parameter] = templateSettings[index].Recommendation +func getParamToTemplateFieldMap(category Category, field string, driver string) ([]DeviceMap, error) { + var deviceTypeMap []DeviceMap + + for _, dev := range deviceTemplate { + var tempMap DeviceMap + + tempMap = DeviceMap{ + deviceMap: make(map[string]string), + } + + for index := range dev.TemplateArray { + + if dev.TemplateArray[index].Category == Category.String(category) { + if driver != "" && dev.TemplateArray[index].Driver != driver { + // obtain only specific driver params in a given category + continue + } + + switch field { + case "recommendation": + // populate parameter -> recommended value map + tempMap.deviceMap[dev.TemplateArray[index].Parameter] = dev.TemplateArray[index].Recommendation + case "description": + // populate parameter -> description map + tempMap.deviceMap[dev.TemplateArray[index].Parameter] = dev.TemplateArray[index].Description + case "severity": + // populate parameter -> severity map + tempMap.deviceMap[dev.TemplateArray[index].Parameter] = dev.TemplateArray[index].Level + default: + // populate parameter -> recommended value map by default + tempMap.deviceMap[dev.TemplateArray[index].Parameter] = dev.TemplateArray[index].Recommendation + } } } + + tempMap.DeviceType = dev.DeviceType + deviceTypeMap = append(deviceTypeMap, tempMap) } - return paramTemplateFieldMap, nil + + return deviceTypeMap, nil } // copyTemplateFile copies the template config files supplied with the tool as destination file @@ -253,7 +349,7 @@ func appendRecommendations(current []*Recommendation, final []*Recommendation) ( } // GetRecommendations obtain various recommendations for non-compliant settings on host -func GetRecommendations() (settings []*Recommendation, err error) { +func GetRecommendations(deviceParam ...string) (settings []*Recommendation, err error) { log.Trace(">>>>> GetRecommendations") defer log.Trace("<<<<< GetRecommendations") @@ -262,13 +358,18 @@ func GetRecommendations() (settings []*Recommendation, err error) { var fileSystemRecommendations []*Recommendation var deviceRecommendations []*Recommendation var iscsiRecommendations []*Recommendation - var multipathRecommendations []*Recommendation var fcRecommendations []*Recommendation - // Get all nimble devices + deviceType := defaultDeviceType + // If no deviceType is passed, we assume Nimble as deviceType + if len(deviceParam) != 0 { + deviceType = deviceParam[0] + } + + // Get all devices devices, err := linux.GetLinuxDmDevices(false, util.GetVolumeObject("", "")) if err != nil { - log.Error("Unable to get Nimble devices ", err.Error()) + log.Error("Unable to get devices ", err.Error()) return nil, err } // Get filesystem recommendations @@ -281,7 +382,7 @@ func GetRecommendations() (settings []*Recommendation, err error) { recommendations, _ = appendRecommendations(fileSystemRecommendations, recommendations) // Get block device recommendations - deviceRecommendations, err = GetDeviceRecommendations(devices) + deviceRecommendations, err = GetDeviceRecommendations(devices, deviceType) if err != nil { log.Error("Unable to get device recommendations ", err.Error()) return nil, err @@ -291,7 +392,7 @@ func GetRecommendations() (settings []*Recommendation, err error) { if _, err = os.Stat(linux.IscsiConf); os.IsNotExist(err) == false { // Get iscsi recommendations - iscsiRecommendations, err = GetIscsiRecommendations() + iscsiRecommendations, err = GetIscsiRecommendations(deviceType) if err != nil { log.Error("Unable to get iscsi recommendations ", err.Error()) return nil, err @@ -301,13 +402,17 @@ func GetRecommendations() (settings []*Recommendation, err error) { } // Get multipath recommendations - multipathRecommendations, err = GetMultipathRecommendations() + multipathRecommendations, err := GetMultipathRecommendations() if err != nil { log.Error("Unable to get multipath recommendations ", err.Error()) return nil, err } // get the appended final list - recommendations, _ = appendRecommendations(multipathRecommendations, recommendations) + for _, mRecomendation := range multipathRecommendations { + if mRecomendation.DeviceType == deviceType { + recommendations, _ = appendRecommendations(mRecomendation.RecomendArray, recommendations) + } + } // Get multipath recommendations fcRecommendations, err = GetFcRecommendations() diff --git a/tunelinux/config/cloud_vm_config.json b/tunelinux/config/cloud_vm_config.json index 3443b7a..1f2ce4d 100644 --- a/tunelinux/config/cloud_vm_config.json +++ b/tunelinux/config/cloud_vm_config.json @@ -1,231 +1,714 @@ -[ - { - "category": "filesystem", - "severity": "info", - "description": "Enable discard option to allow auto space reclamation using UNMAP", - "parameter": "discard", - "recommendation": "enabled" - }, - { - "category": "filesystem", - "severity": "warning", - "description": "Enable _netdev for iSCSI mount devices to allow network to be up before mounting device", - "parameter": "_netdev", - "recommendation": "enabled" - }, - { - "category": "filesystem", - "severity": "info", - "description": "Enable nobarrier to allow write barriers on SSD drives", - "parameter": "nobarrier", - "recommendation": "enabled" - }, - { - "category": "disk", - "severity": "warning", - "description": "Reduce latency by disabling contribution to randomness entroy pool for disk operations. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "add_random", - "recommendation": "0" - }, - { - "category": "disk", - "severity": "warning", - "description": "Request affinity of 2 is recommended to allow I/O completions on different CPU than submission CPU. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "rq_affinity", - "recommendation": "2" - }, - { - "category": "disk", - "severity": "warning", - "description": "Scheduler noop is recommended to remove I/O request sorting overhead for SSD disks. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "scheduler", - "recommendation": "noop" - }, - { - "category": "disk", - "severity": "warning", - "description": "Set rotational to 0 to indicate SSD disks. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "rotational", - "recommendation": "0" - }, - { - "category": "disk", - "severity": "warning", - "description": "Set minimum I/O request allocations to 512. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "nr_requests", - "recommendation": "512" - }, - { - "category": "disk", - "severity": "warning", - "description": "Set maximum I/O request size to 4MB in case of sequential I/O. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "max_sectors_kb", - "recommendation": "4096" - }, - { - "category": "iscsi", - "severity": "warning", - "description": "Automatically startup and login to all discovered sessions during system reboot. Can be set in /etc/iscsi/iscsid.conf", - "parameter": "startup", - "recommendation": "automatic" - }, - { - "category": "iscsi", - "severity": "warning", - "description": "Replacement_timeout of 10 seconds is recommended for faster failover of I/O by multipath on path failures. Can be set in /etc/iscsi/iscsid.conf", - "parameter": "replacement_timeout", - "recommendation": "10" - }, - { - "category": "iscsi", - "severity": "warning", - "description": "Minimum login timeout of 15 seconds is recommended with iSCSI. Can be set in /etc/iscsi/iscsid.conf", - "parameter": "login_timeout", - "recommendation": "15" - }, - { - "category": "iscsi", - "severity": "warning", - "description": "Minimum timeout of 10 seconds is recommended with noop requests. Can be set in /etc/iscsi/iscsid.conf", - "parameter": "noop_out_timeout", - "recommendation": "10" - }, - { - "category": "iscsi", - "severity": "info", - "description": "Minimum cmds_max of 256 is recommended for each session if handling multiple LUN's. Can be set in /etc/iscsi/iscsid.conf", - "parameter": "cmds_max", - "recommendation": "256" - }, - { - "category": "iscsi", - "severity": "warning", - "description": "Minimum queue_depth of 64 is recommended for each iSCSI session/path. Can be set in /etc/iscsi/iscsid.conf", - "parameter": "queue_depth", - "recommendation": "64" - }, - { - "category": "iscsi", - "severity": "info", - "description": "Minimum number of sessions per iSCSI login is recommended to be 1 by default. If additional sessions are needed this can be set in /etc/iscsi/iscsid.conf. If NCM is running, please change min_session_per_array in /etc/ncm.conf and restart nlt service instead", - "parameter": "nr_sessions", - "recommendation": "4" - }, - { - "category": "multipath", - "severity": "critical", - "description": "product attribute recommended to be set to Server in /etc/multipath.conf", - "parameter": "product", - "recommendation": "\"Server\"" - }, - { - "category": "multipath", - "severity": "critical", - "description": "alua prioritizer is recommended. Can be set in /etc/multipath.conf", - "parameter": "prio", - "recommendation": "alua" - }, - { - "category": "multipath", - "severity": "critical", - "description": "scsi_dh_alua device handler is recommended. Can be set in /etc/multipath.conf", - "parameter": "hardware_handler", - "recommendation": "\"1 alua\"" - }, - { - "category": "multipath", - "severity": "warning", - "description": "immediate failback setting is recommended. Can be set in /etc/multipath.conf", - "parameter": "failback", - "recommendation": "immediate" - }, - { - "category": "multipath", - "severity": "critical", - "description": "immediately fail i/o on transient path failures to retry on other paths, value=1. Can be set in /etc/multipath.conf", - "parameter": "fast_io_fail_tmo", - "recommendation": "5" - }, - { - "category": "multipath", - "severity": "critical", - "description": "queueing is recommended for 150 seconds, with no_path_retry value of 30. Can be set in /etc/multipath.conf", - "parameter": "no_path_retry", - "recommendation": "30" - }, - { - "category": "multipath", - "severity": "warning", - "description": "service-time path selector is recommended. Can be set in /etc/multipath.conf", - "parameter": "path_selector", - "recommendation": "\"service-time 0\"" - }, - { - "category": "multipath", - "severity": "critical", - "description": "vendor attribute recommended to be set to Nimble in /etc/multipath.conf", - "parameter": "vendor", - "recommendation": "\"Nimble\"" - }, - { - "category": "multipath", - "severity": "critical", - "description": "group paths according to ALUA path priority of active/standby. Recommended to be set to group_by_prio in /etc/multipath.conf", - "parameter": "path_grouping_policy", - "recommendation": "group_by_prio" - }, - { - "category": "multipath", - "severity": "critical", - "description": "tur path checker is recommended. Can be set in /etc/multipath.conf", - "parameter": "path_checker", - "recommendation": "tur" - }, - { - "category": "multipath", - "severity": "critical", - "description": "infinite value is recommended for timeout in cases of device loss for FC. Can be set in /etc/multipath.conf", - "parameter": "dev_loss_tmo", - "recommendation": "infinity" - }, - { - "category": "fc", - "severity": "warning", - "description": "Minimum queue_depth of 128 is recommended for Qlogic drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", - "parameter": "ql2xmaxqdepth", - "recommendation": "64", - "driver": "qla2xxx" - }, - { - "category": "fc", - "severity": "warning", - "description": "Minimum LUN queue_depth of 128 is recommended for Emulex drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", - "parameter": "lpfc_lun_queue_depth", - "recommendation": "64", - "driver": "lpfc" - }, - { - "category": "fc", - "severity": "warning", - "description": "Minimum HBA queue_depth of 8192 is recommended for Emulex drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", - "parameter": "lpfc_hba_queue_depth", - "recommendation": "8192", - "driver": "lpfc" - }, - { - "category": "fc", - "severity": "warning", - "description": "Minimum LUN queue_depth of 64 is recommended for Cisco FC drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", - "parameter": "fnic_max_qdepth", - "recommendation": "64", - "driver": "fnic" - }, - { - "category": "fc", - "severity": "warning", - "description": "Minimum LUN queue_depth of 64 is recommended for Brocade FC drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", - "parameter": "bfa_lun_queue_depth", - "recommendation": "64", - "driver": "bfa" - } -] +{ + "Nimble": { + "Default": [ + { + "category": "filesystem", + "severity": "info", + "description": "Enable discard option to allow auto space reclamation using UNMAP", + "parameter": "discard", + "recommendation": "enabled" + }, + { + "category": "filesystem", + "severity": "warning", + "description": "Enable _netdev for iSCSI mount devices to allow network to be up before mounting device", + "parameter": "_netdev", + "recommendation": "enabled" + }, + { + "category": "filesystem", + "severity": "info", + "description": "Enable nobarrier to allow write barriers on SSD drives", + "parameter": "nobarrier", + "recommendation": "enabled" + }, + { + "category": "disk", + "severity": "warning", + "description": "Reduce latency by disabling contribution to randomness entroy pool for disk operations. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "add_random", + "recommendation": "0" + }, + { + "category": "disk", + "severity": "warning", + "description": "Request affinity of 2 is recommended to allow I/O completions on different CPU than submission CPU. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "rq_affinity", + "recommendation": "2" + }, + { + "category": "disk", + "severity": "warning", + "description": "Scheduler noop is recommended to remove I/O request sorting overhead for SSD disks. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "scheduler", + "recommendation": "noop" + }, + { + "category": "disk", + "severity": "warning", + "description": "Set rotational to 0 to indicate SSD disks. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "rotational", + "recommendation": "0" + }, + { + "category": "disk", + "severity": "warning", + "description": "Set minimum I/O request allocations to 512. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "nr_requests", + "recommendation": "512" + }, + { + "category": "disk", + "severity": "warning", + "description": "Set maximum I/O request size to 4MB in case of sequential I/O. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "max_sectors_kb", + "recommendation": "4096" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Manual startup of iSCSI nodes on boot. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "startup", + "recommendation": "manual" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Replacement_timeout of 10 seconds is recommended for faster failover of I/O by multipath on path failures. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "replacement_timeout", + "recommendation": "10" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum login timeout of 15 seconds is recommended with iSCSI. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "login_timeout", + "recommendation": "15" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum timeout of 10 seconds is recommended with noop requests. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "noop_out_timeout", + "recommendation": "10" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum cmds_max of 512 is recommended for each session if handling multiple LUN's. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "cmds_max", + "recommendation": "512" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum queue_depth of 256 is recommended for each iSCSI session/path. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "queue_depth", + "recommendation": "256" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum number of sessions per iSCSI login is recommended to be 1 by default. If additional sessions are needed this can be set in /etc/iscsi/iscsid.conf. If NCM is running, please change min_session_per_array in /etc/ncm.conf and restart nlt service instead", + "parameter": "nr_sessions", + "recommendation": "1" + }, + { + "category": "multipath", + "severity": "critical", + "description": "product attribute recommended to be set to Server in /etc/multipath.conf", + "parameter": "product", + "recommendation": "\"Server\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "alua prioritizer is recommended. Can be set in /etc/multipath.conf", + "parameter": "prio", + "recommendation": "alua" + }, + { + "category": "multipath", + "severity": "critical", + "description": "scsi_dh_alua device handler is recommended. Can be set in /etc/multipath.conf", + "parameter": "hardware_handler", + "recommendation": "\"1 alua\"" + }, + { + "category": "multipath", + "severity": "warning", + "description": "immediate failback setting is recommended. Can be set in /etc/multipath.conf", + "parameter": "failback", + "recommendation": "immediate" + }, + { + "category": "multipath", + "severity": "critical", + "description": "immediately fail i/o on transient path failures to retry on other paths, value=1. Can be set in /etc/multipath.conf", + "parameter": "fast_io_fail_tmo", + "recommendation": "5" + }, + { + "category": "multipath", + "severity": "critical", + "description": "queueing is recommended for 150 seconds, with no_path_retry value of 30. Can be set in /etc/multipath.conf", + "parameter": "no_path_retry", + "recommendation": "30" + }, + { + "category": "multipath", + "severity": "warning", + "description": "service-time path selector is recommended. Can be set in /etc/multipath.conf", + "parameter": "path_selector", + "recommendation": "\"service-time 0\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "vendor attribute recommended to be set to Nimble in /etc/multipath.conf", + "parameter": "vendor", + "recommendation": "\"Nimble\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "group paths according to ALUA path priority of active/standby. Recommended to be set to group_by_prio in /etc/multipath.conf", + "parameter": "path_grouping_policy", + "recommendation": "group_by_prio" + }, + { + "category": "multipath", + "severity": "critical", + "description": "tur path checker is recommended. Can be set in /etc/multipath.conf", + "parameter": "path_checker", + "recommendation": "tur" + }, + { + "category": "multipath", + "severity": "critical", + "description": "infinite value is recommended for timeout in cases of device loss for FC. Can be set in /etc/multipath.conf", + "parameter": "dev_loss_tmo", + "recommendation": "infinity" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum queue_depth of 128 is recommended for Qlogic drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "ql2xmaxqdepth", + "recommendation": "64", + "driver": "qla2xxx" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum LUN queue_depth of 128 is recommended for Emulex drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "lpfc_lun_queue_depth", + "recommendation": "64", + "driver": "lpfc" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum HBA queue_depth of 8192 is recommended for Emulex drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "lpfc_hba_queue_depth", + "recommendation": "8192", + "driver": "lpfc" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum LUN queue_depth of 64 is recommended for Cisco FC drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "fnic_max_qdepth", + "recommendation": "64", + "driver": "fnic" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum LUN queue_depth of 64 is recommended for Brocade FC drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "bfa_lun_queue_depth", + "recommendation": "64", + "driver": "bfa" + } + ], + "Ubuntu": null + }, + "3PARdata": { + "Default": [ + { + "category": "filesystem", + "severity": "info", + "description": "Enable discard option to allow auto space reclamation using UNMAP", + "parameter": "discard", + "recommendation": "enabled" + }, + { + "category": "filesystem", + "severity": "warning", + "description": "Enable _netdev for iSCSI mount devices to allow network to be up before mounting device", + "parameter": "_netdev", + "recommendation": "enabled" + }, + { + "category": "filesystem", + "severity": "info", + "description": "Enable nobarrier to allow write barriers on SSD drives", + "parameter": "nobarrier", + "recommendation": "enabled" + }, + { + "category": "disk", + "severity": "warning", + "description": "Reduce latency by disabling contribution to randomness entroy pool for disk operations. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "add_random", + "recommendation": "0" + }, + { + "category": "disk", + "severity": "warning", + "description": "Request affinity of 2 is recommended to allow I/O completions on different CPU than submission CPU. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "rq_affinity", + "recommendation": "2" + }, + { + "category": "disk", + "severity": "warning", + "description": "Scheduler noop is recommended to remove I/O request sorting overhead for SSD disks. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "scheduler", + "recommendation": "noop" + }, + { + "category": "disk", + "severity": "warning", + "description": "Set rotational to 0 to indicate SSD disks. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "rotational", + "recommendation": "0" + }, + { + "category": "disk", + "severity": "warning", + "description": "Set minimum I/O request allocations to 512. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "nr_requests", + "recommendation": "512" + }, + { + "category": "disk", + "severity": "warning", + "description": "Set maximum I/O request size to 4MB in case of sequential I/O. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "max_sectors_kb", + "recommendation": "4096" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Manual startup of iSCSI nodes on boot. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "startup", + "recommendation": "manual" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Replacement_timeout of 10 seconds is recommended for faster failover of I/O by multipath on path failures. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "replacement_timeout", + "recommendation": "10" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum login timeout of 15 seconds is recommended with iSCSI. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "login_timeout", + "recommendation": "15" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum timeout of 10 seconds is recommended with noop requests. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "noop_out_timeout", + "recommendation": "10" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum cmds_max of 512 is recommended for each session if handling multiple LUN's. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "cmds_max", + "recommendation": "512" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum queue_depth of 256 is recommended for each iSCSI session/path. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "queue_depth", + "recommendation": "256" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum number of sessions per iSCSI login is recommended to be 1 by default. If additional sessions are needed this can be set in /etc/iscsi/iscsid.conf. If NCM is running, please change min_session_per_array in /etc/ncm.conf and restart nlt service instead", + "parameter": "nr_sessions", + "recommendation": "1" + }, + { + "category": "multipath", + "severity": "critical", + "description": "product attribute recommended to be set to Server in /etc/multipath.conf", + "parameter": "product", + "recommendation": "\"VV\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "alua prioritizer is recommended. Can be set in /etc/multipath.conf", + "parameter": "prio", + "recommendation": "alua" + }, + { + "category": "multipath", + "severity": "critical", + "description": "scsi_dh_alua device handler is recommended. Can be set in /etc/multipath.conf", + "parameter": "hardware_handler", + "recommendation": "\"1 alua\"" + }, + { + "category": "multipath", + "severity": "warning", + "description": "immediate failback setting is recommended. Can be set in /etc/multipath.conf", + "parameter": "failback", + "recommendation": "immediate" + }, + { + "category": "multipath", + "severity": "critical", + "description": "immediately fail i/o on transient path failures to retry on other paths, value=1. Can be set in /etc/multipath.conf", + "parameter": "fast_io_fail_tmo", + "recommendation": "10" + }, + { + "category": "multipath", + "severity": "critical", + "description": "queueing is recommended for 150 seconds, with no_path_retry value of 30. Can be set in /etc/multipath.conf", + "parameter": "no_path_retry", + "recommendation": "18" + }, + { + "category": "multipath", + "severity": "warning", + "description": "round-robin 0 path selector is recommended. Can be set in /etc/multipath.conf", + "parameter": "path_selector", + "recommendation": "\"round-robin 0\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "vendor attribute recommended to be set to Nimble in /etc/multipath.conf", + "parameter": "vendor", + "recommendation": "\"3PARdata\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "group paths according to ALUA path priority of active/standby. Recommended to be set to group_by_prio in /etc/multipath.conf", + "parameter": "path_grouping_policy", + "recommendation": "group_by_prio" + }, + { + "category": "multipath", + "severity": "critical", + "description": "infinite value is recommended for timeout in cases of device loss for FC. Can be set in /etc/multipath.conf", + "parameter": "dev_loss_tmo", + "recommendation": "infinity" + }, + { + "category": "multipath", + "severity": "critical", + "description": "tur path checker is recommended. Can be set in /etc/multipath.conf", + "parameter": "path_checker", + "recommendation": "tur" + }, + { + "category": "multipath", + "severity": "critical", + "description": "0 value is recommended for features. Can be set in /etc/multipath.conf", + "parameter": "features", + "recommendation": "\"0\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "uniform rr_weight is recommended. Can be set in /etc/multipath.conf", + "parameter": "rr_weight", + "recommendation": "\"uniform\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "rr_min_io_rq 1 is recommended. Can be set in /etc/multipath.conf", + "parameter": "rr_min_io_rq", + "recommendation": "1" + }, + { + "category": "multipath", + "severity": "critical", + "description": "detect_prio yes is recommended. Can be set in /etc/multipath.conf", + "parameter": "detect_prio", + "recommendation": "yes" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum queue_depth of 128 is recommended for Qlogic drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "ql2xmaxqdepth", + "recommendation": "64", + "driver": "qla2xxx" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum LUN queue_depth of 128 is recommended for Emulex drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "lpfc_lun_queue_depth", + "recommendation": "64", + "driver": "lpfc" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum HBA queue_depth of 8192 is recommended for Emulex drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "lpfc_hba_queue_depth", + "recommendation": "8192", + "driver": "lpfc" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum LUN queue_depth of 64 is recommended for Cisco FC drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "fnic_max_qdepth", + "recommendation": "64", + "driver": "fnic" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum LUN queue_depth of 64 is recommended for Brocade FC drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "bfa_lun_queue_depth", + "recommendation": "64", + "driver": "bfa" + } + ], + "Ubuntu": [ + { + "category": "filesystem", + "severity": "info", + "description": "Enable discard option to allow auto space reclamation using UNMAP", + "parameter": "discard", + "recommendation": "enabled" + }, + { + "category": "filesystem", + "severity": "warning", + "description": "Enable _netdev for iSCSI mount devices to allow network to be up before mounting device", + "parameter": "_netdev", + "recommendation": "enabled" + }, + { + "category": "filesystem", + "severity": "info", + "description": "Enable nobarrier to allow write barriers on SSD drives", + "parameter": "nobarrier", + "recommendation": "enabled" + }, + { + "category": "disk", + "severity": "warning", + "description": "Reduce latency by disabling contribution to randomness entroy pool for disk operations. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "add_random", + "recommendation": "0" + }, + { + "category": "disk", + "severity": "warning", + "description": "Request affinity of 2 is recommended to allow I/O completions on different CPU than submission CPU. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "rq_affinity", + "recommendation": "2" + }, + { + "category": "disk", + "severity": "warning", + "description": "Scheduler noop is recommended to remove I/O request sorting overhead for SSD disks. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "scheduler", + "recommendation": "noop" + }, + { + "category": "disk", + "severity": "warning", + "description": "Set rotational to 0 to indicate SSD disks. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "rotational", + "recommendation": "0" + }, + { + "category": "disk", + "severity": "warning", + "description": "Set minimum I/O request allocations to 512. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "nr_requests", + "recommendation": "512" + }, + { + "category": "disk", + "severity": "warning", + "description": "Set maximum I/O request size to 4MB in case of sequential I/O. Can be tuned by UDEV using 99-nimble-tune.rules", + "parameter": "max_sectors_kb", + "recommendation": "4096" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Automatic startup of iSCSI nodes on boot. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "startup", + "recommendation": "automatic" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Replacement_timeout of 10 seconds is recommended for faster failover of I/O by multipath on path failures. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "replacement_timeout", + "recommendation": "10" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum interval of 15 seconds is recommended with iSCSI. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "noop_out_interval", + "recommendation": "10" + }, + { + "category": "multipath", + "severity": "critical", + "description": "product attribute recommended to be set to Server in /etc/multipath.conf", + "parameter": "product", + "recommendation": "\"VV\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "alua prioritizer is recommended. Can be set in /etc/multipath.conf", + "parameter": "prio", + "recommendation": "alua" + }, + { + "category": "multipath", + "severity": "critical", + "description": "scsi_dh_alua device handler is recommended. Can be set in /etc/multipath.conf", + "parameter": "hardware_handler", + "recommendation": "\"1 alua\"" + }, + { + "category": "multipath", + "severity": "warning", + "description": "immediate failback setting is recommended. Can be set in /etc/multipath.conf", + "parameter": "failback", + "recommendation": "immediate" + }, + { + "category": "multipath", + "severity": "critical", + "description": "queueing is recommended for 150 seconds, with no_path_retry value of 30. Can be set in /etc/multipath.conf", + "parameter": "no_path_retry", + "recommendation": "18" + }, + { + "category": "multipath", + "severity": "warning", + "description": "round-robin 0 path selector is recommended. Can be set in /etc/multipath.conf", + "parameter": "path_selector", + "recommendation": "\"round-robin 0\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "vendor attribute recommended to be set to Nimble in /etc/multipath.conf", + "parameter": "vendor", + "recommendation": "\"3PARdata\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "group paths according to ALUA path priority of active/standby. Recommended to be set to group_by_prio in /etc/multipath.conf", + "parameter": "path_grouping_policy", + "recommendation": "group_by_prio" + }, + { + "category": "multipath", + "severity": "critical", + "description": "getuid_callout whitelist is recommended. Can be set in /etc/multipath.conf", + "parameter": "getuid_callout", + "recommendation": "\"/lib/udev/scsi_id --whitelisted --device=/dev/%n\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "rr_min_io is recommended with value as 100. Can be set in /etc/multipath.conf", + "parameter": "rr_min_io", + "recommendation": "100" + }, + { + "category": "multipath", + "severity": "critical", + "description": " checker is recommended. Can be set in /etc/multipath.conf", + "parameter": "checker", + "recommendation": "tur" + }, + { + "category": "multipath", + "severity": "critical", + "description": " tur path checker is recommended. Can be set in /etc/multipath.conf", + "parameter": "path_checker", + "recommendation": "tur" + }, + { + "category": "multipath", + "severity": "critical", + "description": " features 0 is recommended. Can be set in /etc/multipath.conf", + "parameter": "features", + "recommendation": "\"0\"" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum queue_depth of 128 is recommended for Qlogic drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "ql2xmaxqdepth", + "recommendation": "64", + "driver": "qla2xxx" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum LUN queue_depth of 128 is recommended for Emulex drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "lpfc_lun_queue_depth", + "recommendation": "64", + "driver": "lpfc" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum HBA queue_depth of 8192 is recommended for Emulex drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "lpfc_hba_queue_depth", + "recommendation": "8192", + "driver": "lpfc" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum LUN queue_depth of 64 is recommended for Cisco FC drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "fnic_max_qdepth", + "recommendation": "64", + "driver": "fnic" + }, + { + "category": "fc", + "severity": "warning", + "description": "Minimum LUN queue_depth of 64 is recommended for Brocade FC drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", + "parameter": "bfa_lun_queue_depth", + "recommendation": "64", + "driver": "bfa" + } + ] + } +} \ No newline at end of file diff --git a/tunelinux/config/config.json b/tunelinux/config/config.json index f1087bf..f93d47f 100644 --- a/tunelinux/config/config.json +++ b/tunelinux/config/config.json @@ -1,238 +1,405 @@ -[ - { - "category": "filesystem", - "severity": "info", - "description": "Enable discard option to allow auto space reclamation using UNMAP", - "parameter": "discard", - "recommendation": "enabled" - }, - { - "category": "filesystem", - "severity": "warning", - "description": "Enable _netdev for iSCSI mount devices to allow network to be up before mounting device", - "parameter": "_netdev", - "recommendation": "enabled" - }, - { - "category": "filesystem", - "severity": "info", - "description": "Enable nobarrier to allow write barriers on SSD drives", - "parameter": "nobarrier", - "recommendation": "enabled" - }, - { - "category": "disk", - "severity": "warning", - "description": "Reduce latency by disabling contribution to randomness entroy pool for disk operations. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "add_random", - "recommendation": "0" - }, - { - "category": "disk", - "severity": "warning", - "description": "Request affinity of 2 is recommended to allow I/O completions on different CPU than submission CPU. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "rq_affinity", - "recommendation": "2" - }, - { - "category": "disk", - "severity": "warning", - "description": "Scheduler noop is recommended to remove I/O request sorting overhead for SSD disks. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "scheduler", - "recommendation": "noop" - }, - { - "category": "disk", - "severity": "warning", - "description": "Set rotational to 0 to indicate SSD disks. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "rotational", - "recommendation": "0" - }, - { - "category": "disk", - "severity": "warning", - "description": "Set minimum I/O request allocations to 512. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "nr_requests", - "recommendation": "512" - }, - { - "category": "disk", - "severity": "warning", - "description": "Set maximum I/O request size to 4MB in case of sequential I/O. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "max_sectors_kb", - "recommendation": "4096" - }, - { - "category": "disk", - "severity": "warning", - "description": "Set the maximum number of kilobytes that the operating system may read ahead during a sequential read operation. Can be tuned by UDEV using 99-nimble-tune.rules", - "parameter": "read_ahead_kb", - "recommendation": "128" - }, - { - "category": "iscsi", - "severity": "warning", - "description": "Automatically startup and login to all discovered sessions during system reboot. Can be set in /etc/iscsi/iscsid.conf", - "parameter": "startup", - "recommendation": "automatic" - }, - { - "category": "iscsi", - "severity": "warning", - "description": "Replacement_timeout of 10 seconds is recommended for faster failover of I/O by multipath on path failures. Can be set in /etc/iscsi/iscsid.conf", - "parameter": "replacement_timeout", - "recommendation": "10" - }, - { - "category": "iscsi", - "severity": "warning", - "description": "Minimum login timeout of 15 seconds is recommended with iSCSI. Can be set in /etc/iscsi/iscsid.conf", - "parameter": "login_timeout", - "recommendation": "15" - }, - { - "category": "iscsi", - "severity": "warning", - "description": "Minimum timeout of 10 seconds is recommended with noop requests. Can be set in /etc/iscsi/iscsid.conf", - "parameter": "noop_out_timeout", - "recommendation": "10" - }, - { - "category": "iscsi", - "severity": "info", - "description": "Minimum cmds_max of 256 is recommended for each session if handling multiple LUN's. Can be set in /etc/iscsi/iscsid.conf", - "parameter": "cmds_max", - "recommendation": "256" - }, - { - "category": "iscsi", - "severity": "warning", - "description": "Minimum queue_depth of 64 is recommended for each iSCSI session/path. Can be set in /etc/iscsi/iscsid.conf", - "parameter": "queue_depth", - "recommendation": "256" - }, - { - "category": "iscsi", - "severity": "info", - "description": "Minimum number of sessions per iSCSI login is recommended to be 1 by default. If additional sessions are needed this can be set in /etc/iscsi/iscsid.conf. If NCM is running, please change min_session_per_array in /etc/ncm.conf and restart nlt service instead", - "parameter": "nr_sessions", - "recommendation": "1" - }, - { - "category": "multipath", - "severity": "critical", - "description": "product attribute recommended to be set to Server in /etc/multipath.conf", - "parameter": "product", - "recommendation": "\"Server\"" - }, - { - "category": "multipath", - "severity": "critical", - "description": "alua prioritizer is recommended. Can be set in /etc/multipath.conf", - "parameter": "prio", - "recommendation": "alua" - }, - { - "category": "multipath", - "severity": "critical", - "description": "scsi_dh_alua device handler is recommended. Can be set in /etc/multipath.conf", - "parameter": "hardware_handler", - "recommendation": "\"1 alua\"" - }, - { - "category": "multipath", - "severity": "warning", - "description": "immediate failback setting is recommended. Can be set in /etc/multipath.conf", - "parameter": "failback", - "recommendation": "immediate" - }, - { - "category": "multipath", - "severity": "critical", - "description": "immediately fail i/o on transient path failures to retry on other paths, value=1. Can be set in /etc/multipath.conf", - "parameter": "fast_io_fail_tmo", - "recommendation": "5" - }, - { - "category": "multipath", - "severity": "critical", - "description": "queueing is recommended for 150 seconds, with no_path_retry value of 30. Can be set in /etc/multipath.conf", - "parameter": "no_path_retry", - "recommendation": "30" - }, - { - "category": "multipath", - "severity": "warning", - "description": "service-time path selector is recommended. Can be set in /etc/multipath.conf", - "parameter": "path_selector", - "recommendation": "\"service-time 0\"" - }, - { - "category": "multipath", - "severity": "critical", - "description": "vendor attribute recommended to be set to Nimble in /etc/multipath.conf", - "parameter": "vendor", - "recommendation": "\"Nimble\"" - }, - { - "category": "multipath", - "severity": "critical", - "description": "group paths according to ALUA path priority of active/standby. Recommended to be set to group_by_prio in /etc/multipath.conf", - "parameter": "path_grouping_policy", - "recommendation": "group_by_prio" - }, - { - "category": "multipath", - "severity": "critical", - "description": "tur path checker is recommended. Can be set in /etc/multipath.conf", - "parameter": "path_checker", - "recommendation": "tur" - }, - { - "category": "multipath", - "severity": "critical", - "description": "infinite value is recommended for timeout in cases of device loss for FC. Can be set in /etc/multipath.conf", - "parameter": "dev_loss_tmo", - "recommendation": "infinity" - }, - { - "category": "fc", - "severity": "warning", - "description": "Minimum queue_depth of 128 is recommended for Qlogic drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", - "parameter": "ql2xmaxqdepth", - "recommendation": "64", - "driver": "qla2xxx" - }, - { - "category": "fc", - "severity": "warning", - "description": "Minimum LUN queue_depth of 128 is recommended for Emulex drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", - "parameter": "lpfc_lun_queue_depth", - "recommendation": "64", - "driver": "lpfc" - }, - { - "category": "fc", - "severity": "warning", - "description": "Minimum HBA queue_depth of 8192 is recommended for Emulex drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", - "parameter": "lpfc_hba_queue_depth", - "recommendation": "8192", - "driver": "lpfc" - }, - { - "category": "fc", - "severity": "warning", - "description": "Minimum LUN queue_depth of 64 is recommended for Cisco FC drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", - "parameter": "fnic_max_qdepth", - "recommendation": "64", - "driver": "fnic" - }, - { - "category": "fc", - "severity": "warning", - "description": "Minimum LUN queue_depth of 64 is recommended for Brocade FC drivers. Set using modprobe.conf, rebuild initramfs and reboot system.", - "parameter": "bfa_lun_queue_depth", - "recommendation": "64", - "driver": "bfa" - } -] +{ + "Nimble": { + "Default": [ + { + "category": "iscsi", + "severity": "warning", + "description": "Manual startup of iSCSI nodes on boot. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "startup", + "recommendation": "manual" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Replacement_timeout of 10 seconds is recommended for faster failover of I/O by multipath on path failures. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "replacement_timeout", + "recommendation": "10" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum login timeout of 15 seconds is recommended with iSCSI. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "login_timeout", + "recommendation": "15" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum timeout of 10 seconds is recommended with noop requests. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "noop_out_timeout", + "recommendation": "10" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum cmds_max of 512 is recommended for each session if handling multiple LUN's. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "cmds_max", + "recommendation": "512" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum queue_depth of 256 is recommended for each iSCSI session/path. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "queue_depth", + "recommendation": "256" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum number of sessions per iSCSI login is recommended to be 1 by default. If additional sessions are needed this can be set in /etc/iscsi/iscsid.conf. If NCM is running, please change min_session_per_array in /etc/ncm.conf and restart nlt service instead", + "parameter": "nr_sessions", + "recommendation": "1" + }, + { + "category": "multipath", + "severity": "critical", + "description": "product attribute recommended to be set to Server in /etc/multipath.conf", + "parameter": "product", + "recommendation": "\"Server\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "alua prioritizer is recommended. Can be set in /etc/multipath.conf", + "parameter": "prio", + "recommendation": "alua" + }, + { + "category": "multipath", + "severity": "critical", + "description": "scsi_dh_alua device handler is recommended. Can be set in /etc/multipath.conf", + "parameter": "hardware_handler", + "recommendation": "\"1 alua\"" + }, + { + "category": "multipath", + "severity": "warning", + "description": "immediate failback setting is recommended. Can be set in /etc/multipath.conf", + "parameter": "failback", + "recommendation": "immediate" + }, + { + "category": "multipath", + "severity": "critical", + "description": "immediately fail i/o on transient path failures to retry on other paths, value=1. Can be set in /etc/multipath.conf", + "parameter": "fast_io_fail_tmo", + "recommendation": "5" + }, + { + "category": "multipath", + "severity": "critical", + "description": "queueing is recommended for 150 seconds, with no_path_retry value of 30. Can be set in /etc/multipath.conf", + "parameter": "no_path_retry", + "recommendation": "30" + }, + { + "category": "multipath", + "severity": "warning", + "description": "service-time path selector is recommended. Can be set in /etc/multipath.conf", + "parameter": "path_selector", + "recommendation": "\"service-time 0\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "vendor attribute recommended to be set to Nimble in /etc/multipath.conf", + "parameter": "vendor", + "recommendation": "\"Nimble\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "group paths according to ALUA path priority of active/standby. Recommended to be set to group_by_prio in /etc/multipath.conf", + "parameter": "path_grouping_policy", + "recommendation": "group_by_prio" + }, + { + "category": "multipath", + "severity": "critical", + "description": "tur path checker is recommended. Can be set in /etc/multipath.conf", + "parameter": "path_checker", + "recommendation": "tur" + }, + { + "category": "multipath", + "severity": "critical", + "description": "infinite value is recommended for timeout in cases of device loss for FC. Can be set in /etc/multipath.conf", + "parameter": "dev_loss_tmo", + "recommendation": "infinity" + } + ], + "Ubuntu": null + }, + "3PARdata": { + "Default": [ + { + "category": "iscsi", + "severity": "warning", + "description": "Manual startup of iSCSI nodes on boot. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "startup", + "recommendation": "manual" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Replacement_timeout of 10 seconds is recommended for faster failover of I/O by multipath on path failures. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "replacement_timeout", + "recommendation": "10" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum login timeout of 15 seconds is recommended with iSCSI. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "login_timeout", + "recommendation": "15" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum timeout of 10 seconds is recommended with noop requests. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "noop_out_timeout", + "recommendation": "10" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum cmds_max of 512 is recommended for each session if handling multiple LUN's. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "cmds_max", + "recommendation": "512" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum queue_depth of 256 is recommended for each iSCSI session/path. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "queue_depth", + "recommendation": "256" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum number of sessions per iSCSI login is recommended to be 1 by default. If additional sessions are needed this can be set in /etc/iscsi/iscsid.conf. If NCM is running, please change min_session_per_array in /etc/ncm.conf and restart nlt service instead", + "parameter": "nr_sessions", + "recommendation": "1" + }, + { + "category": "multipath", + "severity": "critical", + "description": "product attribute recommended to be set to VV in /etc/multipath.conf", + "parameter": "product", + "recommendation": "\"VV\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "alua prioritizer is recommended. Can be set in /etc/multipath.conf", + "parameter": "prio", + "recommendation": "alua" + }, + { + "category": "multipath", + "severity": "critical", + "description": "scsi_dh_alua device handler is recommended. Can be set in /etc/multipath.conf", + "parameter": "hardware_handler", + "recommendation": "\"1 alua\"" + }, + { + "category": "multipath", + "severity": "warning", + "description": "immediate failback setting is recommended. Can be set in /etc/multipath.conf", + "parameter": "failback", + "recommendation": "immediate" + }, + { + "category": "multipath", + "severity": "critical", + "description": "immediately fail i/o on transient path failures to retry on other paths, value=1. Can be set in /etc/multipath.conf", + "parameter": "fast_io_fail_tmo", + "recommendation": "10" + }, + { + "category": "multipath", + "severity": "critical", + "description": "queueing is recommended for 150 seconds, with no_path_retry value of 18. Can be set in /etc/multipath.conf", + "parameter": "no_path_retry", + "recommendation": "18" + }, + { + "category": "multipath", + "severity": "warning", + "description": "round-robin 0 path selector is recommended. Can be set in /etc/multipath.conf", + "parameter": "path_selector", + "recommendation": "\"round-robin 0\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "vendor attribute recommended to be set to 3PARdata. Can be set in /etc/multipath.conf", + "parameter": "vendor", + "recommendation": "\"3PARdata\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "group paths according to ALUA path priority of active/standby. Recommended to be set to group_by_prio in /etc/multipath.conf", + "parameter": "path_grouping_policy", + "recommendation": "group_by_prio" + }, + { + "category": "multipath", + "severity": "critical", + "description": "infinite value is recommended for timeout in cases of device loss for FC. Can be set in /etc/multipath.conf", + "parameter": "dev_loss_tmo", + "recommendation": "infinity" + }, + { + "category": "multipath", + "severity": "critical", + "description": "tur path checker is recommended. Can be set in /etc/multipath.conf", + "parameter": "path_checker", + "recommendation": "tur" + }, + { + "category": "multipath", + "severity": "critical", + "description": "0 value is recommended for features. Can be set in /etc/multipath.conf", + "parameter": "features", + "recommendation": "\"0\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "uniform rr_weight is recommended. Can be set in /etc/multipath.conf", + "parameter": "rr_weight", + "recommendation": "\"uniform\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "rr_min_io_rq 1 is recommended. Can be set in /etc/multipath.conf", + "parameter": "rr_min_io_rq", + "recommendation": "1" + }, + { + "category": "multipath", + "severity": "critical", + "description": "detect_prio yes is recommended. Can be set in /etc/multipath.conf", + "parameter": "detect_prio", + "recommendation": "yes" + } + ], + "Ubuntu": [ + { + "category": "iscsi", + "severity": "warning", + "description": "Automatic startup of iSCSI nodes on boot. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "startup", + "recommendation": "automatic" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Replacement_timeout of 10 seconds is recommended for faster failover of I/O by multipath on path failures. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "replacement_timeout", + "recommendation": "10" + }, + { + "category": "iscsi", + "severity": "warning", + "description": "Minimum interval of 10 seconds is recommended with noop requests. Can be set in /etc/iscsi/iscsid.conf", + "parameter": "noop_out_interval", + "recommendation": "10" + }, + { + "category": "multipath", + "severity": "critical", + "description": "product attribute recommended to be set to VV in /etc/multipath.conf", + "parameter": "product", + "recommendation": "\"VV\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "alua prioritizer is recommended. Can be set in /etc/multipath.conf", + "parameter": "prio", + "recommendation": "alua" + }, + { + "category": "multipath", + "severity": "critical", + "description": "scsi_dh_alua device handler is recommended. Can be set in /etc/multipath.conf", + "parameter": "hardware_handler", + "recommendation": "\"1 alua\"" + }, + { + "category": "multipath", + "severity": "warning", + "description": "immediate failback setting is recommended. Can be set in /etc/multipath.conf", + "parameter": "failback", + "recommendation": "immediate" + }, + { + "category": "multipath", + "severity": "critical", + "description": "queueing is recommended for 150 seconds, with no_path_retry value of 18. Can be set in /etc/multipath.conf", + "parameter": "no_path_retry", + "recommendation": "18" + }, + { + "category": "multipath", + "severity": "warning", + "description": "round-robin 0 path selector is recommended. Can be set in /etc/multipath.conf", + "parameter": "path_selector", + "recommendation": "\"round-robin 0\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "vendor attribute recommended to be set to 3PARdata in /etc/multipath.conf", + "parameter": "vendor", + "recommendation": "\"3PARdata\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "group paths according to ALUA path priority of active/standby. Recommended to be set to group_by_prio in /etc/multipath.conf", + "parameter": "path_grouping_policy", + "recommendation": "group_by_prio" + }, + { + "category": "multipath", + "severity": "critical", + "description": "getuid_callout whitelist is recommended. Can be set in /etc/multipath.conf", + "parameter": "getuid_callout", + "recommendation": "\"/lib/udev/scsi_id --whitelisted --device=/dev/%n\"" + }, + { + "category": "multipath", + "severity": "critical", + "description": "rr_min_io is recommended with value as 100. Can be set in /etc/multipath.conf", + "parameter": "rr_min_io", + "recommendation": "100" + }, + { + "category": "multipath", + "severity": "critical", + "description": " tur checker is recommended. Can be set in /etc/multipath.conf", + "parameter": "checker", + "recommendation": "tur" + }, + { + "category": "multipath", + "severity": "critical", + "description": " tur path checker is recommended. Can be set in /etc/multipath.conf", + "parameter": "path_checker", + "recommendation": "tur" + }, + { + "category": "multipath", + "severity": "critical", + "description": " features 0 is recommended. Can be set in /etc/multipath.conf", + "parameter": "features", + "recommendation": "\"0\"" + } + ] + } +} diff --git a/tunelinux/config/multipath.conf.generic b/tunelinux/config/multipath.conf.generic index ad4b067..5ffa172 100644 --- a/tunelinux/config/multipath.conf.generic +++ b/tunelinux/config/multipath.conf.generic @@ -47,19 +47,6 @@ devices { device { vendor "3PARdata" product "VV" - path_grouping_policy "group_by_prio" - path_selector "round-robin 0" - path_checker tur - features "0" - hardware_handler "1 alua" - prio "alua" - failback immediate - rr_weight "uniform" - no_path_retry 18 - rr_min_io_rq 1 - detect_prio yes - fast_io_fail_tmo 10 - dev_loss_tmo "infinity" } device { rr_weight priorities diff --git a/tunelinux/config/multipath.conf.upstream b/tunelinux/config/multipath.conf.upstream index 2a619c6..36b8e17 100644 --- a/tunelinux/config/multipath.conf.upstream +++ b/tunelinux/config/multipath.conf.upstream @@ -49,19 +49,6 @@ devices { device { vendor "3PARdata" product "VV" - path_grouping_policy "group_by_prio" - path_selector "round-robin 0" - path_checker tur - features "0" - hardware_handler "1 alua" - prio "alua" - failback immediate - rr_weight "uniform" - no_path_retry 18 - rr_min_io_rq 1 - detect_prio yes - fast_io_fail_tmo 10 - dev_loss_tmo "infinity" } device { rr_weight priorities diff --git a/tunelinux/disk.go b/tunelinux/disk.go index f8fa736..04d72b5 100644 --- a/tunelinux/disk.go +++ b/tunelinux/disk.go @@ -3,13 +3,14 @@ package tunelinux // Copyright 2019 Hewlett Packard Enterprise Development LP. import ( "fmt" + "io/ioutil" + "regexp" + "strings" + "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" "github.com/hpe-storage/common-host-libs/util" - "io/ioutil" - "regexp" - "strings" ) const ( @@ -46,7 +47,7 @@ func getBlockParamRecommendation(param string, value string, recommended string) } // getBlockQueueRecommendation obtains recommendation for given block queue parameter and value -func getBlockQueueRecommendation(device *model.Device, param string, value string) (setting *Recommendation, err error) { +func getBlockQueueRecommendation(device *model.Device, param string, value string, deviceType string) (setting *Recommendation, err error) { log.Trace("getBlockQueueRecommendation called") var optionSetting *Recommendation var recommendation string @@ -63,25 +64,31 @@ func getBlockQueueRecommendation(device *model.Device, param string, value strin value = scheduler } // Get recommendation settings for given parameter and value obtained - recommendation, status = getBlockParamRecommendation(param, value, blockParamMap[param]) - optionSetting = &Recommendation{ - ID: linux.HashMountID(param + device.AltFullPathName + device.SerialNumber), - Category: Category.String(Disk), - Level: blockParamSeverityMap[param], - Description: blockParamDescriptionMap[param], - Parameter: param, - Value: value, - Recommendation: recommendation, - CompliantStatus: status, - Device: All, - FsType: "", - Vendor: "", + + for index, dev := range blockParamMap { + if dev.DeviceType == deviceType { + recommendation, status = getBlockParamRecommendation(param, value, blockParamMap[index].deviceMap[param]) + optionSetting = &Recommendation{ + ID: linux.HashMountID(param + device.AltFullPathName + device.SerialNumber), + Category: Category.String(Disk), + Level: blockParamSeverityMap[index].deviceMap[param], + Description: blockParamDescriptionMap[index].deviceMap[param], + Parameter: param, + Value: value, + Recommendation: recommendation, + CompliantStatus: status, + Device: All, + FsType: "", + Vendor: "", + } + } } return optionSetting, nil + } // GetBlockQueueRecommendations obtain block queue settings of the device -func GetBlockQueueRecommendations(device *model.Device) (settings []*Recommendation, err error) { +func GetBlockQueueRecommendations(device *model.Device, deviceType string) (settings []*Recommendation, err error) { log.Trace("GetBlockQueueRecommendations called with ", device.AltFullPathName) // Read block queue settings and keep adding recommendations params := []string{"add_random", "rq_affinity", "scheduler", "rotational", "nr_requests", "max_sectors_kb", "read_ahead_kb"} @@ -96,7 +103,7 @@ func GetBlockQueueRecommendations(device *model.Device) (settings []*Recommendat continue } paramValue := strings.TrimRight(string(value), "\n") - optionSetting, err := getBlockQueueRecommendation(device, param, string(paramValue)) + optionSetting, err := getBlockQueueRecommendation(device, param, string(paramValue), deviceType) if err != nil { log.Error("Unable to get block queue recommendation for ", device.AltFullPathName, " param ", param, " value ", string(value)) } @@ -106,18 +113,24 @@ func GetBlockQueueRecommendations(device *model.Device) (settings []*Recommendat } // GetDeviceRecommendations obtain various recommendations for block device settings on host -func GetDeviceRecommendations(devices []*model.Device) (settings []*Recommendation, err error) { +func GetDeviceRecommendations(devices []*model.Device, deviceParam ...string) (settings []*Recommendation, err error) { log.Trace("GetDeviceRecommendations called") var recommendations []*Recommendation var deviceRecommendations []*Recommendation - // load settings from template config file + + // If no deviceType is passed, we assume Nimble as deviceType + deviceType := "Nimble" + if len(deviceParam) != 0 { + deviceType = deviceParam[0] + } + err = loadTemplateSettings() if err != nil { return nil, err } for _, device := range devices { // get device specific recommendations - deviceRecommendations, err = GetBlockQueueRecommendations(device) + deviceRecommendations, err = GetBlockQueueRecommendations(device, deviceType) if err != nil { log.Error("Unable to get recommendations for block device queue parameters ", err.Error()) return nil, err diff --git a/tunelinux/fc.go b/tunelinux/fc.go index b7441a5..4c2ea12 100644 --- a/tunelinux/fc.go +++ b/tunelinux/fc.go @@ -4,11 +4,12 @@ package tunelinux import ( "errors" "fmt" - "github.com/hpe-storage/common-host-libs/linux" - log "github.com/hpe-storage/common-host-libs/logger" "io/ioutil" "os" "strings" + + "github.com/hpe-storage/common-host-libs/linux" + log "github.com/hpe-storage/common-host-libs/logger" ) // HbaVendor indicates the vendor type of the Fibre Channel HBA @@ -146,9 +147,6 @@ func getFcModuleParamRecommendations(module string) (settings []*Recommendation, log.Trace("getFcModuleParamRecommendations called with module ", module) var recommendation *Recommendation var recommendations []*Recommendation - var paramMap map[string]string - var paramDescriptionMap map[string]string - var paramSeverityMap map[string]string // load template recommendations from config file err = loadTemplateSettings() @@ -156,27 +154,31 @@ func getFcModuleParamRecommendations(module string) (settings []*Recommendation, return nil, err } - paramMap, _ = getParamToTemplateFieldMap(Fc, "recommendation", module) - paramDescriptionMap, _ = getParamToTemplateFieldMap(Fc, "description", module) - paramSeverityMap, _ = getParamToTemplateFieldMap(Fc, "severity", module) - - for key, value := range paramMap { - path := fmt.Sprintf("/sys/module/%s/parameters/%s", module, key) - _, err = os.Stat(path) - if err != nil { - log.Trace("parameter path not found for module ", module, " ", key) - return nil, err - } - out, _ := ioutil.ReadFile(path) - currentValue := string(out) - description := paramDescriptionMap[key] - severity := paramSeverityMap[key] - recommendation, err = getFcParamRecommendation(module, key, strings.TrimRight(currentValue, "\n"), value, description, severity) - if err != nil { - log.Trace("parameter recommendation failed for module ", module, " ", key) - return nil, err + paramMap, _ := getParamToTemplateFieldMap(Fc, "recommendation", module) + paramDescriptionMap, _ := getParamToTemplateFieldMap(Fc, "description", module) + paramSeverityMap, _ := getParamToTemplateFieldMap(Fc, "severity", module) + + for index, dev := range paramMap { + if dev.DeviceType == defaultDeviceType { + for key, value := range paramMap[index].deviceMap { + path := fmt.Sprintf("/sys/module/%s/parameters/%s", module, key) + _, err = os.Stat(path) + if err != nil { + log.Trace("parameter path not found for module ", module, " ", key) + return nil, err + } + out, _ := ioutil.ReadFile(path) + currentValue := string(out) + description := paramDescriptionMap[index].deviceMap[key] + severity := paramSeverityMap[index].deviceMap[key] + recommendation, err = getFcParamRecommendation(module, key, strings.TrimRight(currentValue, "\n"), value, description, severity) + if err != nil { + log.Trace("parameter recommendation failed for module ", module, " ", key) + return nil, err + } + recommendations = append(recommendations, recommendation) + } } - recommendations = append(recommendations, recommendation) } return recommendations, err } diff --git a/tunelinux/iscsi.go b/tunelinux/iscsi.go index cf53606..5aec190 100644 --- a/tunelinux/iscsi.go +++ b/tunelinux/iscsi.go @@ -3,13 +3,14 @@ package tunelinux // Copyright 2019 Hewlett Packard Enterprise Development LP. import ( "errors" - "github.com/hpe-storage/common-host-libs/linux" - log "github.com/hpe-storage/common-host-libs/logger" - "github.com/hpe-storage/common-host-libs/util" "io/ioutil" "os" "regexp" "strings" + + "github.com/hpe-storage/common-host-libs/linux" + log "github.com/hpe-storage/common-host-libs/logger" + "github.com/hpe-storage/common-host-libs/util" ) const ( @@ -169,7 +170,7 @@ func IsIscsiEnabled() (enabled bool) { } // GetIscsiRecommendations obtain various recommendations for iSCSI settings on host -func GetIscsiRecommendations() (settings []*Recommendation, err error) { +func GetIscsiRecommendations(deviceParam ...string) (settings []*Recommendation, err error) { log.Trace("GetIscsiRecommendations called") // check if iscsi services are installed and enabled @@ -188,6 +189,12 @@ func GetIscsiRecommendations() (settings []*Recommendation, err error) { iscsiParamDescriptionMap, _ := getParamToTemplateFieldMap(Iscsi, "description", "") iscsiParamSeverityMap, _ := getParamToTemplateFieldMap(Iscsi, "severity", "") + // If no deviceType is passed, we assume Nimble as deviceType + deviceType := "Nimble" + if len(deviceParam) != 0 { + deviceType = deviceParam[0] + } + configLock.Lock() defer configLock.Unlock() content, err := ioutil.ReadFile(linux.IscsiConf) @@ -197,23 +204,28 @@ func GetIscsiRecommendations() (settings []*Recommendation, err error) { } lines := strings.Split(string(content), "\n") // get recommendation for each param in the map matching with the iscsid.conf param - for param, recommendedValue := range iscsiParamMap { - formattedParam, _ := getIscsiFormattedParam(param) - for _, line := range lines { - if false == strings.HasPrefix(line, formattedParam) { - // skip other parameters in iscsid.conf - continue - } - var description = iscsiParamDescriptionMap[param] - var severity = iscsiParamSeverityMap[param] - recommendation, err = getIscsiParamRecommendation(param, recommendedValue, line, description, severity) - if err != nil { - log.Error("Unable to get recommendation for iscsi param ", param, "error: ", err.Error()) - } - if recommendation != nil { - recommendations = append(recommendations, recommendation) + + for index, dev := range iscsiParamMap { + if dev.DeviceType == deviceType { + for param, recommendedValue := range iscsiParamMap[index].deviceMap { + formattedParam, _ := getIscsiFormattedParam(param) + for _, line := range lines { + if false == strings.HasPrefix(line, formattedParam) { + // skip other parameters in iscsid.conf + continue + } + var description = iscsiParamDescriptionMap[index].deviceMap[param] + var severity = iscsiParamSeverityMap[index].deviceMap[param] + recommendation, err = getIscsiParamRecommendation(param, recommendedValue, line, description, severity) + if err != nil { + log.Error("Unable to get recommendation for iscsi param ", param, "error: ", err.Error()) + } + if recommendation != nil { + recommendations = append(recommendations, recommendation) + } + break + } } - break } } // ignore errors during iface recommendations diff --git a/tunelinux/multipath.go b/tunelinux/multipath.go index a584a50..55bca17 100644 --- a/tunelinux/multipath.go +++ b/tunelinux/multipath.go @@ -19,10 +19,16 @@ const ( multipath = "multipath" // multipath params - deviceBlockPattern = "(?s)devices\\s+{\\s*.*device\\s*{(?P.*Nimble.*?)}" multipathParamPattern = "\\s*(?P.*?)\\s+(?P.*)" ) +var ( + deviceBlockPattern = map[string]string{ + "Nimble": "(?s)devices\\s+{\\s*.*device\\s*{(?P.*Nimble.*?)}", + "3par": "(?s)devices\\s+{\\s*.*device\\s*{(?P.*3PAR.*?)}", + } +) + // GetMultipathConfigFile returns path of the template multipath.conf file according to OS distro func GetMultipathTemplateFile() (configFile string, err error) { log.Traceln(">>>>> GetMultipathTemplateFile") @@ -99,62 +105,71 @@ func getMultipathDeviceParamRecommendation(paramKey string, currentValue string, } // getMultipathDeviceScopeRecommendations obtain recommendations for block section of multipath.conf -func getMultipathDeviceScopeRecommendations(deviceBlock string) (settings []*Recommendation, err error) { +func getMultipathDeviceScopeRecommendations(deviceBlock string) (settings []DeviceRecommendation, err error) { log.Trace("getMultipathDeviceScopeRecommendations called") - var recommendations []*Recommendation var recommendation *Recommendation + var deviceRecommendations []DeviceRecommendation var keyFound bool var paramValue string var paramKey string + deviceBlockRecommendationMap, _ := getParamToTemplateFieldMap(Multipath, "recommendation", "") deviceSettingsDescriptionMap, _ := getParamToTemplateFieldMap(Multipath, "description", "") deviceSettingsSeverityMap, _ := getParamToTemplateFieldMap(Multipath, "severity", "") // get individual parameters from device block currentSettings := strings.Split(string(deviceBlock), "\n") - for key := range deviceBlockRecommendationMap { - keyFound = false - for _, setting := range currentSettings { - if setting != "" { - r := regexp.MustCompile(multipathParamPattern) - // extract key value from parameter string - if r.MatchString(setting) { - result := util.FindStringSubmatchMap(setting, r) - paramKey = result["name"] - paramValue = result["value"] - } else { - log.Error("Invalid multipath device param value for recommendation ", setting) + + for index, _ := range deviceBlockRecommendationMap { + + var currRecommendation DeviceRecommendation + for key := range deviceBlockRecommendationMap[index].deviceMap { + + keyFound = false + for _, setting := range currentSettings { + if setting != "" { + r := regexp.MustCompile(multipathParamPattern) + // extract key value from parameter string + if r.MatchString(setting) { + result := util.FindStringSubmatchMap(setting, r) + paramKey = result["name"] + paramValue = result["value"] + } else { + log.Error("Invalid multipath device param value for recommendation ", setting) + continue + } + if paramKey == key { + // found the matching key for recommended parameter in /etc/multipath.conf + keyFound = true + break + } + } + } + var description = deviceSettingsDescriptionMap[index].deviceMap[key] + var recommendedValue = deviceBlockRecommendationMap[index].deviceMap[key] + var severity = deviceSettingsSeverityMap[index].deviceMap[key] + if keyFound == true { + log.Info(" Keyfound = ", keyFound) + // entry found in /etc/multipath.conf + recommendation, err = getMultipathDeviceParamRecommendation(paramKey, strings.TrimSpace(paramValue), recommendedValue, description, severity) + if err != nil { + log.Error("Unable to get recommendation for multipath param", paramKey, "value ", paramValue) continue } - if paramKey == key { - // found the matching key for recommended parameter in /etc/multipath.conf - keyFound = true - break + } else { + // missing needed parameters in /etc/multipath.conf + recommendation, err = getMultipathDeviceParamRecommendation(key, "", recommendedValue, description, severity) + if err != nil { + log.Error("Unable to get recommendation for multipath param", paramKey, "value ", paramValue) + continue } } + currRecommendation.RecomendArray = append(currRecommendation.RecomendArray, recommendation) } - var description = deviceSettingsDescriptionMap[key] - var recommendedValue = deviceBlockRecommendationMap[key] - var severity = deviceSettingsSeverityMap[key] - if keyFound == true { - // entry found in /etc/multipath.conf - recommendation, err = getMultipathDeviceParamRecommendation(paramKey, strings.TrimSpace(paramValue), recommendedValue, description, severity) - if err != nil { - log.Error("Unable to get recommendation for multipath param", paramKey, "value ", paramValue) - continue - } - } else { - // missing needed parameters in /etc/multipath.conf - recommendation, err = getMultipathDeviceParamRecommendation(key, "", recommendedValue, description, severity) - if err != nil { - log.Error("Unable to get recommendation for multipath param", paramKey, "value ", paramValue) - continue - } - } - // append the recommendation to the list - recommendations = append(recommendations, recommendation) + currRecommendation.DeviceType = deviceBlockRecommendationMap[index].DeviceType + deviceRecommendations = append(deviceRecommendations, currRecommendation) } - return recommendations, nil + return deviceRecommendations, nil } // IsMultipathRequired returns if multipath needs to be enabled on the system @@ -175,9 +190,9 @@ func IsMultipathRequired() (required bool, err error) { } // GetMultipathRecommendations obtain various recommendations for multipath settings on host -func GetMultipathRecommendations() (settings []*Recommendation, err error) { +func GetMultipathRecommendations() (settings []DeviceRecommendation, err error) { log.Trace("GetMultipathRecommendations called") - var deviceRecommendations []*Recommendation + var deviceRecommendations []DeviceRecommendation var isMultipathRequired bool @@ -197,39 +212,40 @@ func GetMultipathRecommendations() (settings []*Recommendation, err error) { return nil, err } - // Check if /etc/multipath.conf present - if _, err = os.Stat(linux.MultipathConf); os.IsNotExist(err) { - log.Error("/etc/multipath.conf file missing") - // Generate All Recommendations By default - deviceRecommendations, err = getMultipathDeviceScopeRecommendations("") - if err != nil { - log.Error("Unable to get recommendations for multipath device settings ", err.Error()) + for _, devicePattern := range deviceBlockPattern { + // Check if /etc/multipath.conf present + if _, err = os.Stat(linux.MultipathConf); os.IsNotExist(err) { + log.Error("/etc/multipath.conf file missing") + // Generate All Recommendations By default + deviceRecommendations, err = getMultipathDeviceScopeRecommendations("") + if err != nil { + log.Error("Unable to get recommendations for multipath device settings ", err.Error()) + } + return deviceRecommendations, err } - return deviceRecommendations, err - } - // Obtain contents of /etc/multipath.conf - content, err := ioutil.ReadFile(linux.MultipathConf) - if err != nil { - log.Error(err.Error()) - return nil, err - } - - // Obtain device block - r := regexp.MustCompile(deviceBlockPattern) - if r.MatchString(string(content)) { - // found Nimble Device block - result := util.FindStringSubmatchMap(string(content), r) - deviceBlock := result["device_block"] - deviceRecommendations, err = getMultipathDeviceScopeRecommendations(strings.TrimSpace(deviceBlock)) + // Obtain contents of /etc/multipath.conf + content, err := ioutil.ReadFile(linux.MultipathConf) if err != nil { - log.Error("Unable to get recommendations for multipath device settings ", err.Error()) + log.Error(err.Error()) + return nil, err } - } else { - // Nimble device section missing. - // Generate All Recommendations By default - deviceRecommendations, err = getMultipathDeviceScopeRecommendations("") - if err != nil { - log.Error("Unable to get recommendations for multipath device settings ", err.Error()) + + r := regexp.MustCompile(devicePattern) + if r.MatchString(string(content)) { + // found Device block + result := util.FindStringSubmatchMap(string(content), r) + deviceBlock := result["device_block"] + deviceRecommendations, err = getMultipathDeviceScopeRecommendations(strings.TrimSpace(deviceBlock)) + if err != nil { + log.Error("Unable to get recommendations for multipath device settings ", err.Error()) + } + } else { + // Device section missing. + // Generate All Recommendations By default + deviceRecommendations, err = getMultipathDeviceScopeRecommendations("") + if err != nil { + log.Error("Unable to get recommendations for multipath device settings ", err.Error()) + } } } @@ -237,7 +253,7 @@ func GetMultipathRecommendations() (settings []*Recommendation, err error) { } // setMultipathRecommendations sets device scope recommendations in multipath.conf -func setMultipathRecommendations(recommendations []*Recommendation) (err error) { +func setMultipathRecommendations(recommendations []*Recommendation, device string) (err error) { var devicesSection *mpathconfig.Section var deviceSection *mpathconfig.Section var defaultsSection *mpathconfig.Section @@ -247,11 +263,11 @@ func setMultipathRecommendations(recommendations []*Recommendation) (err error) return err } - deviceSection, err = config.GetNimbleSection() + deviceSection, err = config.GetDeviceSection(device) if err != nil { - // Nimble device section is not found, get or create devices{} and then add device{} section devicesSection, err = config.GetSection("devices", "") if err != nil { + // Device section is not found, get or create devices{} and then add device{} section devicesSection, err = config.AddSection("devices", config.GetRoot()) if err != nil { return errors.New("Unable to add new devices section") @@ -301,23 +317,8 @@ func SetMultipathRecommendations() (err error) { // Take a backup of existing multipath.conf f, err := os.Stat(linux.MultipathConf) - if err == nil && f.Size() != 0 { - // Get current recommendations - var recommendations []*Recommendation - recommendations, err = GetMultipathRecommendations() - if err != nil { - return err - } - if len(recommendations) == 0 { - log.Info("no recommendations found for multipath.conf settings") - return nil - } - // Apply new recommendations for mismatched values - err = setMultipathRecommendations(recommendations) - if err != nil { - return err - } - } else { + + if err != nil || f.Size() == 0 { multipathTemplate, err := GetMultipathTemplateFile() if err != nil { return err @@ -328,6 +329,23 @@ func SetMultipathRecommendations() (err error) { return err } } + // Get current recommendations + recommendations, err := GetMultipathRecommendations() + if err != nil { + return err + } + if len(recommendations) == 0 { + log.Warning("no recommendations found for multipath.conf settings") + return nil + } + + // Apply new recommendations for mismatched values + for _, dev := range recommendations { + err = setMultipathRecommendations(dev.RecomendArray, dev.DeviceType) + } + if err != nil { + return err + } // Start service as it would have failed to start initially if multipath.conf is missing err = linux.ServiceCommand(multipath, "start") if err != nil {