github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/pkg/seachest/seachest.go (about)

     1  //go:build linux && cgo
     2  // +build linux,cgo
     3  
     4  /*
     5  Copyright 2018 The OpenEBS Authors.
     6  Licensed under the Apache License, Version 2.0 (the "License");
     7  you may not use this file except in compliance with the License.
     8  You may obtain a copy of the License at
     9      http://www.apache.org/licenses/LICENSE-2.0
    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 seachest
    18  
    19  /*
    20  #cgo LDFLAGS: -lopensea-operations -lopensea-transport -lopensea-common -lm
    21  #cgo CFLAGS: -I/usr/local/include/openSeaChest -I/usr/local/include/openSeaChest/opensea-common -I/usr/local/include/openSeaChest/opensea-operations -I/usr/local/include/openSeaChest/opensea-transport
    22  #cgo CFLAGS: -I../../../openSeaChest/include -I../../../openSeaChest/opensea-common/include -I../../../openSeaChest/opensea-operations/include -I../../../openSeaChest/opensea-transport/include
    23  #include "common.h"
    24  #include "openseachest_util_options.h"
    25  #include "common_public.h"
    26  #include "ata_helper.h"
    27  #include "ata_helper_func.h"
    28  #include "scsi_helper.h"
    29  #include "scsi_helper_func.h"
    30  #include "nvme_helper.h"
    31  #include "nvme_helper_func.h"
    32  #include "cmds.h"
    33  #include "drive_info.h"
    34  #include <libudev.h>
    35  */
    36  import "C"
    37  import (
    38  	"fmt"
    39  	"github.com/openebs/node-disk-manager/blockdevice"
    40  	"unsafe"
    41  
    42  	"k8s.io/klog/v2"
    43  )
    44  
    45  // Seachest errors are converted to string using this function
    46  func SeachestErrors(err int) string {
    47  	seachestErrorSting := []string{
    48  		"Success",
    49  		"Failed",
    50  		"Not Supported",
    51  		"Cmd Failure",
    52  		"In-progress",
    53  		"Aborted",
    54  		"Bad Parameter",
    55  		"Memory Allocation Failed",
    56  		"Cmd Passthrough Failed",
    57  		"Library Mismatch",
    58  		"Device Frozen",
    59  		"Permission Denied",
    60  		"File Open Error",
    61  		"Incomplete RFTRS",
    62  		"Cmd Time-out",
    63  		"Warning - Not all device enumerated",
    64  		"Invalid Checksum",
    65  		"Cmd not Available",
    66  		"Cmd Blocked",
    67  		"Cmd Interrupted",
    68  		"Unknown",
    69  	}
    70  	return seachestErrorSting[err]
    71  }
    72  
    73  // Identifier (devPath such as /dev/sda,etc) is an identifier for seachest probe
    74  type Identifier struct {
    75  	DevPath string
    76  }
    77  
    78  func (I *Identifier) SeachestBasicDiskInfo() (*C.driveInformationSAS_SATA, int) {
    79  
    80  	var device C.tDevice
    81  	var Drive C.driveInformationSAS_SATA
    82  	str := C.CString(I.DevPath)
    83  	defer C.free(unsafe.Pointer(str))
    84  
    85  	err := int(C.get_Device(str, &device))
    86  	if err != 0 {
    87  		klog.Errorf("Unable to get device info for device:%s with error:%s", I.DevPath, SeachestErrors(err))
    88  		return nil, err
    89  	}
    90  	// close the device, once all info is fetched
    91  	defer closeDevice(&device, I.DevPath)
    92  
    93  	err = int(C.get_SCSI_Drive_Information(&device, &Drive))
    94  	if err != 0 {
    95  		klog.Errorf("Unable to get derive info for device:%s with error:%s", I.DevPath, SeachestErrors(err))
    96  		return nil, err
    97  	}
    98  
    99  	return &Drive, err
   100  }
   101  
   102  // closeDevice closes the device and log the error if any
   103  func closeDevice(device *C.tDevice, devPath string) {
   104  	err := int(C.close_Device(device))
   105  	if err != 0 {
   106  		klog.Errorf("unable to close device: %s with error: %s", devPath, SeachestErrors(err))
   107  	}
   108  }
   109  
   110  func (I *Identifier) GetHostName(driveInfo *C.driveInformationSAS_SATA) string {
   111  	return ""
   112  }
   113  
   114  func (I *Identifier) GetModelNumber(driveInfo *C.driveInformationSAS_SATA) string {
   115  	var ptr *C.char
   116  	ptr = &driveInfo.modelNumber[0]
   117  	str := C.GoString(ptr)
   118  	return str
   119  }
   120  
   121  func (I *Identifier) GetUuid(driveInfo *C.driveInformationSAS_SATA) string {
   122  	myString := fmt.Sprintf("%v", driveInfo.worldWideName)
   123  	return myString
   124  }
   125  
   126  func (I *Identifier) GetCapacity(driveInfo *C.driveInformationSAS_SATA) uint64 {
   127  	var capacity C.uint64_t
   128  	capacity = (C.uint64_t)(driveInfo.maxLBA * ((C.uint64_t)(driveInfo.logicalSectorSize)))
   129  	return ((uint64)(capacity))
   130  }
   131  
   132  func (I *Identifier) GetSerialNumber(driveInfo *C.driveInformationSAS_SATA) string {
   133  	var ptr *C.char
   134  	ptr = &driveInfo.serialNumber[0]
   135  	str := C.GoString(ptr)
   136  	return str
   137  }
   138  
   139  func (I *Identifier) GetVendorID(driveInfo *C.driveInformationSAS_SATA) string {
   140  	var ptr *C.char
   141  	ptr = &driveInfo.vendorID[0]
   142  	str := C.GoString(ptr)
   143  	return str
   144  }
   145  
   146  func (I *Identifier) GetPath(driveInfo *C.driveInformationSAS_SATA) string {
   147  	return I.DevPath
   148  }
   149  
   150  func (I *Identifier) GetFirmwareRevision(driveInfo *C.driveInformationSAS_SATA) string {
   151  	var ptr *C.char
   152  	ptr = &driveInfo.firmwareRevision[0]
   153  	str := C.GoString(ptr)
   154  	return str
   155  }
   156  
   157  func (I *Identifier) GetLogicalSectorSize(driveInfo *C.driveInformationSAS_SATA) uint32 {
   158  	return ((uint32)(driveInfo.logicalSectorSize))
   159  }
   160  
   161  func (I *Identifier) GetPhysicalSectorSize(driveInfo *C.driveInformationSAS_SATA) uint32 {
   162  	return ((uint32)(driveInfo.physicalSectorSize))
   163  }
   164  
   165  func (I *Identifier) GetRotationRate(driveInfo *C.driveInformationSAS_SATA) uint16 {
   166  	if driveInfo.rotationRate > 1 {
   167  		return ((uint16)(driveInfo.rotationRate))
   168  	}
   169  	return 0
   170  }
   171  
   172  func (I *Identifier) GetRotationalLatency(driveInfo *C.driveInformationSAS_SATA) float64 {
   173  	if driveInfo.rotationRate > 1 {
   174  		// latency = 1/rpm/60
   175  		// Formula reference: https://sciencing.com/calculate-rotational-latency-8559684.html
   176  		rpm := (uint16)(driveInfo.rotationRate)
   177  		rps := float64(rpm / 60)
   178  		latency := float64(1 / rps)
   179  		return latency
   180  	}
   181  	return 0
   182  }
   183  
   184  func (I *Identifier) DriveType(driveInfo *C.driveInformationSAS_SATA) string {
   185  
   186  	if driveInfo.rotationRate == 0x0000 {
   187  		return blockdevice.DriveTypeUnknown
   188  	}
   189  
   190  	if driveInfo.rotationRate == 0x0001 {
   191  		return blockdevice.DriveTypeSSD
   192  	}
   193  	return blockdevice.DriveTypeHDD
   194  }
   195  
   196  func (I *Identifier) GetTotalBytesRead(driveInfo *C.driveInformationSAS_SATA) uint64 {
   197  	return ((uint64)(driveInfo.totalBytesRead))
   198  }
   199  
   200  func (I *Identifier) GetTotalBytesWritten(driveInfo *C.driveInformationSAS_SATA) uint64 {
   201  	return ((uint64)(driveInfo.totalBytesWritten))
   202  }
   203  
   204  func (I *Identifier) GetDeviceUtilizationRate(driveInfo *C.driveInformationSAS_SATA) float64 {
   205  	return ((float64)(driveInfo.deviceReportedUtilizationRate))
   206  }
   207  
   208  func (I *Identifier) GetPercentEnduranceUsed(driveInfo *C.driveInformationSAS_SATA) float64 {
   209  	if driveInfo.percentEnduranceUsed != -1 {
   210  		return ((float64)(driveInfo.percentEnduranceUsed))
   211  	}
   212  	return 0
   213  }
   214  
   215  func (I *Identifier) GetTemperatureDataValidStatus(driveInfo *C.driveInformationSAS_SATA) bool {
   216  	return ((bool)(driveInfo.temperatureData.temperatureDataValid))
   217  }
   218  
   219  func (I *Identifier) GetCurrentTemperature(driveInfo *C.driveInformationSAS_SATA) int16 {
   220  	return ((int16)(driveInfo.temperatureData.currentTemperature))
   221  }
   222  
   223  func (I *Identifier) GetHighestValid(driveInfo *C.driveInformationSAS_SATA) bool {
   224  	return ((bool)(driveInfo.temperatureData.highestValid))
   225  }
   226  
   227  func (I *Identifier) GetHighestTemperature(driveInfo *C.driveInformationSAS_SATA) int16 {
   228  	return ((int16)(driveInfo.temperatureData.highestTemperature))
   229  }
   230  
   231  func (I *Identifier) GetLowestValid(driveInfo *C.driveInformationSAS_SATA) bool {
   232  	return ((bool)(driveInfo.temperatureData.lowestValid))
   233  }
   234  
   235  func (I *Identifier) GetLowestTemperature(driveInfo *C.driveInformationSAS_SATA) int16 {
   236  	return ((int16)(driveInfo.temperatureData.lowestTemperature))
   237  }