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 }