github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/cmd/ndm_daemonset/probe/seachestprobe.go (about)

     1  /*
     2  Copyright 2018 OpenEBS Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package probe
    18  
    19  import (
    20  	"github.com/openebs/node-disk-manager/blockdevice"
    21  	"github.com/openebs/node-disk-manager/cmd/ndm_daemonset/controller"
    22  	"github.com/openebs/node-disk-manager/pkg/seachest"
    23  	"github.com/openebs/node-disk-manager/pkg/util"
    24  	"k8s.io/klog/v2"
    25  )
    26  
    27  // seachest contains required variables for populating diskInfo
    28  type seachestProbe struct {
    29  	// Every new probe needs a controller object to register itself.
    30  	// Here Controller consists of Clientset, kubeClientset, probes, etc which is used to
    31  	// create, update, delete, deactivate the disk resources or list the probes already registered.
    32  	Controller         *controller.Controller
    33  	SeachestIdentifier *seachest.Identifier
    34  }
    35  
    36  const (
    37  	seachestConfigKey     = "seachest-probe"
    38  	seachestProbePriority = 6
    39  )
    40  
    41  var (
    42  	seachestProbeName  = "seachest probe"
    43  	seachestProbeState = defaultEnabled
    44  )
    45  
    46  // init is used to get a controller object and then register itself
    47  var seachestProbeRegister = func() {
    48  	// Get a controller object
    49  	ctrl := <-controller.ControllerBroadcastChannel
    50  	if ctrl == nil {
    51  		klog.Error("unable to configure", seachestProbeName)
    52  		return
    53  	}
    54  	if ctrl.NDMConfig != nil {
    55  		for _, probeConfig := range ctrl.NDMConfig.ProbeConfigs {
    56  			if probeConfig.Key == seachestConfigKey {
    57  				seachestProbeName = probeConfig.Name
    58  				seachestProbeState = util.CheckTruthy(probeConfig.State)
    59  				break
    60  			}
    61  		}
    62  	}
    63  	newRegisterProbe := &registerProbe{
    64  		priority:   seachestProbePriority,
    65  		name:       seachestProbeName,
    66  		state:      seachestProbeState,
    67  		pi:         &seachestProbe{Controller: ctrl},
    68  		controller: ctrl,
    69  	}
    70  	// Here we register the probe (seachest probe in this case)
    71  	newRegisterProbe.register()
    72  }
    73  
    74  // newSeachestProbe returns seachestProbe struct which helps populate diskInfo struct
    75  // with the basic disk details such as logical size, firmware revision, etc
    76  func newSeachestProbe(devPath string) *seachestProbe {
    77  	seachestIdentifier := &seachest.Identifier{
    78  		DevPath: devPath,
    79  	}
    80  	seachestProbe := &seachestProbe{
    81  		SeachestIdentifier: seachestIdentifier,
    82  	}
    83  	return seachestProbe
    84  }
    85  
    86  // Start is mainly used for one time activities such as monitoring.
    87  // It is a part of probe interface but here we does not require to perform
    88  // such activities, hence empty implementation
    89  func (scp *seachestProbe) Start() {}
    90  
    91  // fillDiskDetails fills details in diskInfo struct using information it gets from probe
    92  func (scp *seachestProbe) FillBlockDeviceDetails(blockDevice *blockdevice.BlockDevice) {
    93  	if blockDevice.DevPath == "" {
    94  		klog.Error("seachestIdentifier is found empty, seachest probe will not fill disk details.")
    95  		return
    96  	}
    97  
    98  	seachestProbe := newSeachestProbe(blockDevice.DevPath)
    99  	driveInfo, err := seachestProbe.SeachestIdentifier.SeachestBasicDiskInfo()
   100  	if err != 0 {
   101  		klog.Error(err)
   102  		return
   103  	}
   104  
   105  	if blockDevice.DeviceAttributes.FirmwareRevision == "" {
   106  		blockDevice.DeviceAttributes.FirmwareRevision = seachestProbe.SeachestIdentifier.GetFirmwareRevision(driveInfo)
   107  		klog.V(4).Infof("Disk: %s FirmwareRevision:%s filled by seachest.", blockDevice.DevPath, blockDevice.DeviceAttributes.FirmwareRevision)
   108  	}
   109  
   110  	if blockDevice.DeviceAttributes.LogicalBlockSize == 0 {
   111  		blockDevice.DeviceAttributes.LogicalBlockSize = seachestProbe.SeachestIdentifier.GetLogicalSectorSize(driveInfo)
   112  		klog.V(4).Infof("Disk: %s LogicalBlockSize:%d filled by seachest.", blockDevice.DevPath, blockDevice.DeviceAttributes.LogicalBlockSize)
   113  	}
   114  
   115  	if blockDevice.DeviceAttributes.PhysicalBlockSize == 0 {
   116  		blockDevice.DeviceAttributes.PhysicalBlockSize = seachestProbe.SeachestIdentifier.GetPhysicalSectorSize(driveInfo)
   117  		klog.V(4).Infof("Disk: %s PhysicalBlockSize:%d filled by seachest.", blockDevice.DevPath, blockDevice.DeviceAttributes.PhysicalBlockSize)
   118  	}
   119  
   120  	if blockDevice.DeviceAttributes.DriveType == "" ||
   121  		blockDevice.DeviceAttributes.DriveType == blockdevice.DriveTypeUnknown {
   122  		blockDevice.DeviceAttributes.DriveType = seachestProbe.SeachestIdentifier.DriveType(driveInfo)
   123  		klog.V(4).Infof("Disk: %s DriveType:%s filled by seachest.", blockDevice.DevPath, blockDevice.DeviceAttributes.DriveType)
   124  	}
   125  
   126  	// All the below mentioned fields will be filled in only after BlockDevice struct
   127  	// starts supporting them.
   128  	if blockDevice.SMARTInfo.RotationRate == 0 {
   129  		blockDevice.SMARTInfo.RotationRate = seachestProbe.SeachestIdentifier.GetRotationRate(driveInfo)
   130  		klog.V(4).Infof("Disk: %s RotationRate:%d filled by seachest.", blockDevice.DevPath, blockDevice.SMARTInfo.RotationRate)
   131  	}
   132  
   133  	if blockDevice.SMARTInfo.TotalBytesRead == 0 {
   134  		blockDevice.SMARTInfo.TotalBytesRead = seachestProbe.SeachestIdentifier.GetTotalBytesRead(driveInfo)
   135  		klog.V(4).Infof("Disk: %s TotalBytesRead:%d filled by seachest.", blockDevice.DevPath, blockDevice.SMARTInfo.TotalBytesRead)
   136  	}
   137  
   138  	if blockDevice.SMARTInfo.TotalBytesWritten == 0 {
   139  		blockDevice.SMARTInfo.TotalBytesWritten = seachestProbe.SeachestIdentifier.GetTotalBytesWritten(driveInfo)
   140  		klog.V(4).Infof("Disk: %s TotalBytesWritten:%d filled by seachest.", blockDevice.DevPath, blockDevice.SMARTInfo.TotalBytesWritten)
   141  	}
   142  
   143  	if blockDevice.SMARTInfo.UtilizationRate == 0 {
   144  		blockDevice.SMARTInfo.UtilizationRate = seachestProbe.SeachestIdentifier.GetDeviceUtilizationRate(driveInfo)
   145  		klog.V(4).Infof("Disk: %s UtilizationRate:%f filled by seachest.", blockDevice.DevPath, blockDevice.SMARTInfo.UtilizationRate)
   146  	}
   147  
   148  	if blockDevice.SMARTInfo.PercentEnduranceUsed == 0 {
   149  		blockDevice.SMARTInfo.PercentEnduranceUsed = seachestProbe.SeachestIdentifier.GetPercentEnduranceUsed(driveInfo)
   150  		klog.V(4).Infof("Disk: %s PercentEnduranceUsed:%f filled by seachest.", blockDevice.DevPath, blockDevice.SMARTInfo.PercentEnduranceUsed)
   151  	}
   152  
   153  	blockDevice.SMARTInfo.TemperatureInfo.CurrentTemperatureDataValid = seachestProbe.
   154  		SeachestIdentifier.GetTemperatureDataValidStatus(driveInfo)
   155  
   156  	klog.V(4).Infof("Disk: %s TemperatureDataValid:%t filled by seachest.",
   157  		blockDevice.DevPath, blockDevice.SMARTInfo.TemperatureInfo.CurrentTemperatureDataValid)
   158  
   159  	if blockDevice.SMARTInfo.TemperatureInfo.CurrentTemperatureDataValid == true {
   160  		blockDevice.SMARTInfo.TemperatureInfo.CurrentTemperature = seachestProbe.
   161  			SeachestIdentifier.GetCurrentTemperature(driveInfo)
   162  
   163  		klog.V(4).Infof("Disk: %s CurrentTemperature:%d filled by seachest.",
   164  			blockDevice.DevPath, blockDevice.SMARTInfo.TemperatureInfo.CurrentTemperature)
   165  
   166  	}
   167  
   168  	blockDevice.SMARTInfo.TemperatureInfo.HighestTemperatureDataValid = seachestProbe.
   169  		SeachestIdentifier.GetHighestValid(driveInfo)
   170  
   171  	klog.V(4).Infof("Disk: %s HighestTemperatureDataValid:%t filled by seachest.",
   172  		blockDevice.DevPath, blockDevice.SMARTInfo.TemperatureInfo.HighestTemperatureDataValid)
   173  
   174  	if blockDevice.SMARTInfo.TemperatureInfo.HighestTemperatureDataValid == true {
   175  
   176  		blockDevice.SMARTInfo.TemperatureInfo.HighestTemperature = seachestProbe.
   177  			SeachestIdentifier.GetHighestTemperature(driveInfo)
   178  
   179  		klog.V(4).Infof("Disk: %s HighestTemperature:%d filled by seachest.",
   180  			blockDevice.DevPath, blockDevice.SMARTInfo.TemperatureInfo.HighestTemperature)
   181  	}
   182  	blockDevice.SMARTInfo.TemperatureInfo.LowestTemperatureDataValid = seachestProbe.
   183  		SeachestIdentifier.GetLowestValid(driveInfo)
   184  
   185  	klog.V(4).Infof("Disk: %s LowestValid:%t filled by seachest.",
   186  		blockDevice.DevPath, blockDevice.SMARTInfo.TemperatureInfo.LowestTemperatureDataValid)
   187  
   188  	if blockDevice.SMARTInfo.TemperatureInfo.LowestTemperatureDataValid == true {
   189  		blockDevice.SMARTInfo.TemperatureInfo.LowestTemperature = seachestProbe.
   190  			SeachestIdentifier.GetLowestTemperature(driveInfo)
   191  
   192  		klog.V(4).Infof("Disk: %s LowestTemperature:%d filled by seachest.",
   193  			blockDevice.DevPath, blockDevice.SMARTInfo.TemperatureInfo.LowestTemperature)
   194  	}
   195  }